$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: joel_at_[hidden]
Date: 2008-04-12 20:54:46
Author: djowel
Date: 2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
New Revision: 44358
URL: http://svn.boost.org/trac/boost/changeset/44358
Log:
adding spirit2
Added:
   trunk/boost/spirit/home/classic.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/
   trunk/boost/spirit/home/karma.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/action/
   trunk/boost/spirit/home/karma/action.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/action/action.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/action/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/
   trunk/boost/spirit/home/karma/auxiliary.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/eps.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/functor.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/functor_director.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/lazy.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/auxiliary/none.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/binary/
   trunk/boost/spirit/home/karma/binary.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/binary/binary.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/binary/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/char/
   trunk/boost/spirit/home/karma/char.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/char/char.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/char/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/char/space.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/delimit.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/detail/
   trunk/boost/spirit/home/karma/detail/generate_to.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/detail/ostream_iterator.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/detail/output_iterator.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/detail/string_generate.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/
   trunk/boost/spirit/home/karma/directive.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/alignment_meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/case_meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/center_alignment.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/delimit.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/delimiter_meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/detail/
   trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/detail/left_alignment_generate.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/detail/right_alignment_generate.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/left_alignment.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/right_alignment.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/directive/verbatim.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/domain.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/generate.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/
   trunk/boost/spirit/home/karma/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/detail/
   trunk/boost/spirit/home/karma/nonterminal/detail/rule.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/
   trunk/boost/spirit/home/karma/numeric.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/detail/
   trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/int.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/numeric_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/real.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/real_policies.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/numeric/uint.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/
   trunk/boost/spirit/home/karma/operator.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/alternative.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/detail/
   trunk/boost/spirit/home/karma/operator/detail/alternative.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/detail/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/karma-alt/
   trunk/boost/spirit/home/karma/operator/karma-alt.zip   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/karma-alt/alternative.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/karma-alt/detail/
   trunk/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/kleene.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/list.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/optional.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/plus.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/operator/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/
   trunk/boost/spirit/home/karma/stream.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/detail/
   trunk/boost/spirit/home/karma/stream/detail/format_manip.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/detail/iterator_ostream.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/format_manip.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/stream/stream.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/string/
   trunk/boost/spirit/home/karma/string.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/string/lit.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/string/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/karma/what.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/
   trunk/boost/spirit/home/lex.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/domain.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/
   trunk/boost/spirit/home/lex/lexer.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/action.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/char_token_def.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/detail/
   trunk/boost/spirit/home/lex/lexer/detail/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexer.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexer_actions.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexer_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/
   trunk/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_generate_static.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_iterator.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_lexer.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_lexer.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/string_token_def.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/terminal_director.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/terminal_holder.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/token_def.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer/token_set.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer_lexertl.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/lexer_static_lexertl.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/qi/
   trunk/boost/spirit/home/lex/qi/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/qi/state/
   trunk/boost/spirit/home/lex/qi/state/in_state.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/qi/state/state_switcher.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/qi/utility/
   trunk/boost/spirit/home/lex/qi/utility/plain_token.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/set_state.hpp   (contents, props changed)
   trunk/boost/spirit/home/lex/tokenize_and_parse.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/
   trunk/boost/spirit/home/phoenix.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/algorithm.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/
   trunk/boost/spirit/home/phoenix/bind.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/bind_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/bind_function_object.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/bind_member_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/bind_member_variable.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/detail/
   trunk/boost/spirit/home/phoenix/bind/detail/bind_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/detail/bind_function_object.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/detail/function_ptr.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/container.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/
   trunk/boost/spirit/home/phoenix/core.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/actor.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/argument.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/as_actor.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/basic_environment.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/compose.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/composite.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/
   trunk/boost/spirit/home/phoenix/core/detail/actor.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/basic_environment.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/compose.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/composite.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/composite_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/composite_info.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/detail/function_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/is_actor.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/limits.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/nothing.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/reference.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/core/value.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/detail/
   trunk/boost/spirit/home/phoenix/detail/local_reference.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/detail/type_deduction.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/function/
   trunk/boost/spirit/home/phoenix/function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/function/detail/
   trunk/boost/spirit/home/phoenix/function/detail/function_call.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/function/function.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/fusion/
   trunk/boost/spirit/home/phoenix/fusion.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/fusion/at.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/
   trunk/boost/spirit/home/phoenix/object.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/const_cast.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/construct.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/delete.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/detail/
   trunk/boost/spirit/home/phoenix/object/detail/construct.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/detail/construct_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/detail/new.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/detail/new_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/dynamic_cast.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/new.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/reinterpret_cast.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/object/static_cast.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/
   trunk/boost/spirit/home/phoenix/operator.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/arithmetic.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/bitwise.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/comparison.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/
   trunk/boost/spirit/home/phoenix/operator/detail/binary_compose.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/binary_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/io.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_gen.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_return.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/unary_compose.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/detail/unary_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/if_else.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/io.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/logical.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/member.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/operator/self.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/
   trunk/boost/spirit/home/phoenix/scope.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/detail/
   trunk/boost/spirit/home/phoenix/scope/detail/local_gen.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/detail/local_variable.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/dynamic.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/lambda.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/let.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/local_variable.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/scope/scoped_environment.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/
   trunk/boost/spirit/home/phoenix/statement.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/
   trunk/boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/catch_composite.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/catch_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/switch.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.ipp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/do_while.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/for.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/if.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/switch.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/throw.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/try_catch.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/statement/while.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/
   trunk/boost/spirit/home/phoenix/stl.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/
   trunk/boost/spirit/home/phoenix/stl/algorithm.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/decay_array.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_equal_range.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_find.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_lower_bound.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove_if.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_reverse.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_sort.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_unique.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_upper_bound.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_map.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_set.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_list.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_map.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_set.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_map_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_set_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_list_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_map_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_set_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/iteration.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/querying.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/algorithm/transformation.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/container/
   trunk/boost/spirit/home/phoenix/stl/container.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/container/container.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/stl/container/detail/
   trunk/boost/spirit/home/phoenix/stl/container/detail/container.hpp   (contents, props changed)
   trunk/boost/spirit/home/phoenix/version.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/
   trunk/boost/spirit/home/qi.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/action/
   trunk/boost/spirit/home/qi/action.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/action/action.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/action/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/
   trunk/boost/spirit/home/qi/auxiliary.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/eps.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/functor.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/functor_director.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/lazy.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/none.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/binary/
   trunk/boost/spirit/home/qi/binary.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/binary/binary.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/binary/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/
   trunk/boost/spirit/home/qi/char.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/char.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/char_class.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/char_parser.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/detail/
   trunk/boost/spirit/home/qi/char/detail/range.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/detail/range_functions.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/detail/range_run.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/detail/range_run_impl.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/char/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/
   trunk/boost/spirit/home/qi/debug.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/detail/
   trunk/boost/spirit/home/qi/debug/detail/debug_handler.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/detail/print_node_info.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/minimal_macros.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/simple_debug.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/debug/simple_debug_macros.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/
   trunk/boost/spirit/home/qi/detail/alternative_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/assign_to.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/construct.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/expect_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/fail_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/pass_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/permute_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/detail/string_parse.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/directive/
   trunk/boost/spirit/home/qi/directive.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/directive/lexeme.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/directive/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/directive/omit.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/directive/raw.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/domain.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/
   trunk/boost/spirit/home/qi/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/detail/
   trunk/boost/spirit/home/qi/nonterminal/detail/error_handler.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/detail/rule.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/error_handler_result.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/nonterminal_director.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/rule.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/
   trunk/boost/spirit/home/qi/numeric.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/detail/
   trunk/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/int.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/real.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/real_policies.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/numeric/uint.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/
   trunk/boost/spirit/home/qi/operator.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/alternative.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/and_predicate.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/difference.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/expect.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/kleene.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/list.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/not_predicate.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/optional.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/permutation.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/plus.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/sequence.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/sequence_base.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/operator/sequential_or.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/parse.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/skip.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/
   trunk/boost/spirit/home/qi/stream.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/detail/
   trunk/boost/spirit/home/qi/stream/detail/iterator_istream.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/match_manip.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/stream/stream.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/
   trunk/boost/spirit/home/qi/string.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/detail/
   trunk/boost/spirit/home/qi/string/detail/tst.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/lit.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/symbols.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/tst.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/string/tst_map.hpp   (contents, props changed)
   trunk/boost/spirit/home/qi/what.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/
   trunk/boost/spirit/home/support/algorithm/
   trunk/boost/spirit/home/support/algorithm/any.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/algorithm/any_if.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/algorithm/any_ns.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/argument.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/as_variant.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/ascii.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/attribute_of.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/attribute_transform.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/auxiliary/
   trunk/boost/spirit/home/support/auxiliary/functor_holder.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/auxiliary/meta_function_holder.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/char_class/
   trunk/boost/spirit/home/support/char_class.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/char_class/ascii.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/char_class/iso8859_1.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/char_class/standard.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/char_class/standard_wide.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/component.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/
   trunk/boost/spirit/home/support/detail/container.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/hold_any.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/integer/
   trunk/boost/spirit/home/support/detail/integer/cover_operators.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/integer/endian.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/
   trunk/boost/spirit/home/support/detail/lexer/char_state_machine.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/char_traits.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/consts.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/containers/
   trunk/boost/spirit/home/support/detail/lexer/containers/ptr_list.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/containers/ptr_vector.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/debug.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/generate_cpp.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/generator.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/
   trunk/boost/spirit/home/support/detail/lexer/parser/parser.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/
   trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_helper.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_state.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/end_node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/iteration_node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/leaf_node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/selection_node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/parser/tree/sequence_node.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/partition/
   trunk/boost/spirit/home/support/detail/lexer/partition/charset.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/partition/equivset.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/rules.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/runtime_error.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/serialise.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/size_t.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/state_machine.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/string_token.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/lexer/tokeniser.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/math/
   trunk/boost/spirit/home/support/detail/math/detail/
   trunk/boost/spirit/home/support/detail/math/detail/fp_traits.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/math/fpclassify.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/math/nonfinite_num_facets.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/math/signbit.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/to_narrow.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/unordered/
   trunk/boost/spirit/home/support/detail/unordered/detail/
   trunk/boost/spirit/home/support/detail/unordered/detail/allocator.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/unordered/detail/hash_table.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/unordered/detail/hash_table_impl.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/unordered_map.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/unordered_set.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/values.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/detail/what_function.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iso8859_1.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/
   trunk/boost/spirit/home/support/iterators/detail/
   trunk/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/no_check_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/look_ahead.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/multi_pass.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/meta_grammar/
   trunk/boost/spirit/home/support/meta_grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/meta_grammar/basic_rules.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/meta_grammar/basic_transforms.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/meta_grammar/grammar.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/modifier.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/multi_pass.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/nonterminal/
   trunk/boost/spirit/home/support/nonterminal/detail/
   trunk/boost/spirit/home/support/nonterminal/detail/expand_arg.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/nonterminal/locals.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/nonterminal/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/placeholders.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/safe_bool.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/standard.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/standard_wide.hpp   (contents, props changed)
   trunk/boost/spirit/home/support/unused.hpp   (contents, props changed)
Added: trunk/boost/spirit/home/classic.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/classic.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,10 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_CLASSIC_APRIL_11_2008_0849AM)
+#define BOOST_SPIRIT_CLASSIC_APRIL_11_2008_0849AM
+
+#endif
Added: trunk/boost/spirit/home/karma.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,24 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_CORE_MARCH_06_2007_0833PM)
+#define SPIRIT_KARMA_CORE_MARCH_06_2007_0833PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/char.hpp>
+#include <boost/spirit/home/karma/string.hpp>
+#include <boost/spirit/home/karma/numeric.hpp>
+#include <boost/spirit/home/karma/operator.hpp>
+#include <boost/spirit/home/karma/nonterminal.hpp>
+#include <boost/spirit/home/karma/action.hpp>
+#include <boost/spirit/home/karma/directive.hpp>
+#include <boost/spirit/home/karma/auxiliary.hpp>
+#include <boost/spirit/home/karma/generate.hpp>
+#include <boost/spirit/home/karma/what.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/action.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/action.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_ACTION_MAR_04_2007_0912AM)
+#define BOOST_SPIRIT_KARMA_ACTION_MAR_04_2007_0912AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/action/action.hpp>
+#include <boost/spirit/home/karma/action/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/action/action.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/action/action.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,83 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_ACTION_MAR_07_2007_0851AM)
+#define BOOST_SPIRIT_KARMA_ACTION_MAR_07_2007_0851AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct action
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::left<Component>::type,
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            director;
+
+            typedef typename
+                attribute<Component, Context, unused_type>::type
+            param_type;
+
+            // create a parameter if one is not supplied
+            // this creates a _copy_ of the parameter because the semantic
+            // action likely will change parts of this
+            typename mpl::if_<
+                is_same<typename remove_const<Parameter>::type, unused_type>,
+                param_type,
+                Parameter
+            >::type p = spirit::detail::make_value<param_type>::call(param);
+
+            // call the function, passing the parameter, the context
+            // and a bool flag that the client can set to false to
+            // fail parsing.
+            bool pass = true;
+            spirit::right(component)(
+                spirit::detail::pass_value<param_type>::call(p), ctx, pass);
+
+            return pass &&
+                director::generate(spirit::left(component), sink, ctx, d, p);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            typedef typename
+                spirit::result_of::left<Component>::type::director
+            director;
+            return director::what(spirit::left(component));
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/action/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/action/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_MAR_04_2007_0907AM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_MAR_04_2007_0907AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    struct action;
+    
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // action meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct action_meta_grammar : 
+        meta_grammar::binary_rule<
+            karma::domain, proto::tag::subscript, action,
+            main_meta_grammar, proto::when<proto::_, proto::_arg>
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, action_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, action_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<action_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_AUXILIARY_MAR_26_2007_1225PM)
+#define BOOST_SPIRIT_KARMA_AUXILIARY_MAR_26_2007_1225PM
+
+#include <boost/spirit/home/karma/auxiliary/none.hpp>
+#include <boost/spirit/home/karma/auxiliary/eps.hpp>
+#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
+#include <boost/spirit/home/karma/auxiliary/functor.hpp>
+#include <boost/spirit/home/karma/auxiliary/functor_director.hpp>
+#include <boost/spirit/home/karma/auxiliary/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/eps.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/eps.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,68 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_EPS_APRIL_21_2007_0246PM)
+#define BOOST_SPIRIT_KARMA_EPS_APRIL_21_2007_0246PM
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/at.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct eps_generator
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            karma::delimit(sink, d);
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "eps";
+        }
+    };
+
+    struct semantic_predicate
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            karma::delimit(sink, d);
+            return fusion::at_c<0>(component.elements)(unused, ctx);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "semantic-predicate";
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/functor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/functor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,213 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_FUNCTOR_APR_01_2007_1038AM)
+#define BOOST_SPIRIT_KARMA_FUNCTOR_APR_01_2007_1038AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
+#include <boost/spirit/home/support/auxiliary/meta_function_holder.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/lambda.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit 
+{ 
+    namespace karma
+    {
+        template <typename Functor, typename ParameterMF = Functor>
+        class functor_generator;
+    }
+    
+    namespace result_of
+    {
+        template <typename Functor>
+        struct as_generator
+        {
+            typedef karma::functor_generator<Functor> type;
+        };
+
+        template <typename Functor, typename ParameterMF>
+        struct as_generator_mf
+        {
+            typedef karma::functor_generator<Functor, ParameterMF> type;
+        };
+    }
+
+}}  // boost::spirit
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This struct may be used as a base class for a user defined functor
+    ///////////////////////////////////////////////////////////////////////////
+    struct functor_base
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  The return value of a karma functor is always bool
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Parameter, typename OutputIterator>
+        struct result
+        {
+            typedef bool type;
+        };
+
+// FIXME: It will be possible to specify the return value as a typedef, but for 
+//        that Phoenix will have to be fixed.
+//         typedef bool result_type;
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The expected parameter type of a functor has to be defined using a
+        //  embedded apply metafunction. Normally this will be overloaded by 
+        //  the derived class, but the default is unused type.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Context>
+        struct apply
+        {
+            typedef spirit::unused_type type;
+        };
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The functor generator template may be used to create new generators
+    //  without having to dig into the implementation details of Karma
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Functor, typename ParameterMF>
+    class functor_generator
+      : public proto::extends<
+            typename make_functor_holder<
+                functor_generator<Functor, ParameterMF> const*, 
+                functor_generator<Functor, ParameterMF>
+            >::type,
+            functor_generator<Functor, ParameterMF>
+        > 
+    {
+    private:
+        typedef functor_generator<Functor, ParameterMF> self_type;
+        typedef typename 
+            make_functor_holder<self_type const*, self_type>::type 
+        functor_tag;
+        typedef proto::extends<functor_tag, self_type> base_type;
+
+    public:
+        template <typename Context>
+        struct result 
+          : mpl::apply<ParameterMF, Context>
+        {};
+
+    private:
+        // generate function just delegates to the functor supplied function
+        template <typename OutputIterator, typename Context, typename Parameter>
+        bool 
+        generate (OutputIterator& sink, Context& ctx, Parameter const& p) const
+        {
+            // create an attribute if none is supplied
+            typedef typename result<Context>::type parameter_type;
+            typename mpl::if_<
+                is_same<typename remove_const<Parameter>::type, unused_type>,
+                parameter_type,
+                Parameter const&
+            >::type
+            param = spirit::detail::make_value<parameter_type>::call(p);
+
+            return functor(param, ctx, sink);
+        }
+
+        friend struct functor_director;
+        
+    public:
+        explicit functor_generator()
+          : base_type(make_tag())
+        {
+        }
+
+        functor_generator(Functor const& functor_)
+          : base_type(make_tag()), functor(functor_)
+        {
+        }
+
+        functor_generator(Functor const& functor_, ParameterMF const& mf)
+          : base_type(make_tag()), functor(functor_), mf_(mf)
+        {
+        }
+
+    private:
+        functor_tag make_tag() const
+        {
+            functor_tag xpr = {{ this }};
+            return xpr;
+        }
+        
+        Functor functor;
+        meta_function_holder<Functor, ParameterMF> mf_;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  The as_generator generator function may be used to create a functor 
+    //  generator from a function object (some callable item).
+    //  The supplied functor needs to expose
+    // 
+    //    - an embedded result meta function: 
+    //
+    //          template <typename Parameter, typename OutputIterator>
+    //          struct result
+    //          {
+    //              typedef bool type;
+    //          };
+    //
+    //      which declares 'bool' as the result type of the defined function
+    //      operator and
+    //
+    //    - an embedded apply meta function:
+    //
+    //          template <typename Context>
+    //          struct apply
+    //          {
+    //              typedef unspecified type;
+    //          };
+    //
+    //      which declares the given type as the expected parameter type for 
+    //      the generator to create.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Functor>
+    inline typename result_of::as_generator<Functor>::type
+    as_generator(Functor const& func)
+    {
+        return functor_generator<Functor>(func);
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The as_generator_mf generator function is equivalent to the function
+    //  as_generator above except that the user has explicitly to specify a
+    //  type exposing an embedded apply meta function declaring the expected
+    //  parameter type for the generator to create.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ParameterMF, typename Functor>
+    inline typename result_of::as_generator_mf<Functor, ParameterMF>::type
+    as_generator_mf(Functor const& func, ParameterMF const& mf)
+    {
+        return functor_generator<Functor, ParameterMF>(func, mf);
+    }
+    
+    template <typename ParameterMF, typename Functor>
+    inline typename result_of::as_generator_mf<Functor, ParameterMF>::type
+    as_generator_mf(Functor const& func)
+    {
+        return functor_generator<Functor, ParameterMF>(func, ParameterMF());
+    }
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/functor_director.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/functor_director.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_FUNCTOR_DIRECTOR_APR_01_2007_1041AM)
+#define BOOST_SPIRIT_KARMA_FUNCTOR_DIRECTOR_APR_01_2007_1041AM
+
+#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    // this is the director for all functor generators 
+    struct functor_director
+    {
+        // expected value type of the generator
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef typename 
+                result_of::subject<Component>::type::functor_holder
+            functor_holder;
+            typedef typename functor_holder::functor_type functor_type;
+            
+            typedef typename
+                functor_type::template result<Context>::type 
+            type;
+        };
+
+        // generate functionality, delegates back to the corresponding functor
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            bool result = subject(component).held->generate(sink, ctx, param);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "functor";
+        }
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/lazy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/lazy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,89 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_LAZY_MARCH_27_2007_1231PM)
+#define BOOST_SPIRIT_KARMA_LAZY_MARCH_27_2007_1231PM
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct lazy_generator
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<
+                        subject_type(unused_type, Context)
+                    >::type
+                >::type
+            expr_type;
+
+            typedef typename
+                result_of::as_component<karma::domain, expr_type>::type
+            component_type;
+
+            typedef typename
+                traits::attribute_of<
+                    karma::domain, component_type, Context>::type
+            type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<
+                        subject_type(unused_type, Context)
+                    >::type
+                >::type
+            expr_type;
+
+            typedef typename
+                result_of::as_component<karma::domain, expr_type>::type
+            component_type;
+
+            component_type subject
+                = spirit::as_component(
+                    karma::domain(), 
+                    fusion::at_c<0>(component.elements)(unused, ctx));
+
+            return component_type::director::
+                generate(subject, sink, ctx, d, param);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            std::string result = "lazy[";
+            // FIXME: need to get at the what of the embedded component
+            result += "...";
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,89 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_MARCH_26_2007_1230PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_MARCH_26_2007_1230PM
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit
+{
+    template <typename T, typename Functor>
+    struct functor_holder;
+}}
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct none;
+    struct eps_generator;
+    struct semantic_predicate;
+    struct lazy_generator;
+    struct functor_director;
+    
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // auxiliary generators meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+
+    // none, and lazy
+    struct auxiliary_meta_grammar
+      : proto::or_<
+            meta_grammar::empty_terminal_rule<
+                karma::domain, tag::none, none>,
+            meta_grammar::empty_terminal_rule<
+                karma::domain, tag::eps, eps_generator>,
+            meta_grammar::function1_rule<
+                karma::domain, tag::eps, semantic_predicate>,
+            meta_grammar::function1_rule<
+                karma::domain, tag::lazy, lazy_generator>,
+            meta_grammar::terminal_rule<
+                karma::domain, 
+                functor_holder<proto::_, proto::_>,
+                functor_director
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, auxiliary_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, auxiliary_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<auxiliary_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/auxiliary/none.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/none.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NONE_MARCH_26_2007_1227PM)
+#define BOOST_SPIRIT_KARMA_NONE_MARCH_26_2007_1227PM
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct none
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "none";
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/binary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/binary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0859AM)
+#define BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0859AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/binary/binary.hpp>
+#include <boost/spirit/home/karma/binary/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/binary/binary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,185 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0904AM)
+#define BOOST_SPIRIT_KARMA_BINARY_MAY_04_2007_0904AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/integer/endian.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    namespace detail
+    {
+        template <int bits>
+        struct integer
+        {
+#ifdef BOOST_HAS_LONG_LONG
+            BOOST_MPL_ASSERT_MSG(
+                bits == 8 || bits == 16 || bits == 32 || bits == 64,
+                not_supported_binary_size, ());
+#else
+            BOOST_MPL_ASSERT_MSG(
+                bits == 8 || bits == 16 || bits == 32,
+                not_supported_binary_size, ());
+#endif
+        };
+
+        template <>
+        struct integer<8>
+        {
+            typedef uint_least8_t type;
+        };
+
+        template <>
+        struct integer<16>
+        {
+            typedef uint_least16_t type;
+        };
+
+        template <>
+        struct integer<32>
+        {
+            typedef uint_least32_t type;
+        };
+
+#ifdef BOOST_HAS_LONG_LONG
+        template <>
+        struct integer<64>
+        {
+            typedef uint_least64_t type;
+        };
+#endif
+
+        ///////////////////////////////////////////////////////////////////////
+        template <boost::integer::endianness bits>
+        struct what;
+
+        template <>
+        struct what<boost::integer::native>
+        {
+            static std::string is()
+            {
+                return "native-endian binary";
+            }
+        };
+
+        template <>
+        struct what<boost::integer::little>
+        {
+            static char const* is()
+            {
+                return "little-endian binary";
+            }
+        };
+
+        template <>
+        struct what<boost::integer::big>
+        {
+            static char const* is()
+            {
+                return "big-endian binary";
+            }
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <integer::endianness endian, int bits>
+    struct any_binary_director
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef boost::integer::endian<
+                endian, typename karma::detail::integer<bits>::type, bits
+            > type;
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& /*component*/, OutputIterator& sink,
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param)
+        {
+            typename traits::attribute_of<
+                karma::domain, Component, Context>::type p (param);
+            unsigned char const* bytes =
+                reinterpret_cast<unsigned char const*>(&p);
+
+            for (unsigned int i = 0; i < sizeof(p); ++i)
+                detail::generate_to(sink, *bytes++);
+
+            karma::delimit(sink, d);           // always do post-delimiting
+            return true;
+        }
+
+        // this any_byte_director has no parameter attached, it needs to have
+        // been initialized from a direct literal
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter>
+        static bool
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&,
+            unused_type)
+        {
+            BOOST_MPL_ASSERT_MSG(false,
+                binary_generator_not_usable_without_parameter, ());
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return karma::detail::what<endian>::is();
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <integer::endianness endian, int bits>
+    struct binary_lit_director
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/)
+        {
+            boost::integer::endian<
+                endian, typename karma::detail::integer<bits>::type, bits
+            > p (fusion::at_c<0>(component.elements));
+
+            unsigned char const* bytes =
+                reinterpret_cast<unsigned char const*>(&p);
+
+            for (unsigned int i = 0; i < sizeof(p); ++i)
+                detail::generate_to(sink, *bytes++);
+
+            karma::delimit(sink, d);           // always do post-delimiting
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return karma::detail::what<endian>::is();
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/binary/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/binary/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,259 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_MAY_04_2007_0853AM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_MAY_04_2007_0853AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/support/detail/integer/endian.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    template <integer::endianness endian, int bits>
+    struct any_binary_director;
+    
+    template <integer::endianness endian, int bits>
+    struct binary_lit_director;
+
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of an integer based binary literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_literal_bin_director
+    {
+        typedef binary_lit_director<
+            boost::integer::native, sizeof(T)*CHAR_BIT
+        > type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a binary tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_binary_director;
+
+    // native endian binaries
+    template <>
+    struct extract_binary_director<tag::byte>    
+    {
+        typedef any_binary_director<boost::integer::native, 8> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::word>    
+    {
+        typedef any_binary_director<boost::integer::native, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::dword>    
+    {
+        typedef any_binary_director<boost::integer::native, 32> type;
+    };
+
+    // big endian binaries
+    template <>
+    struct extract_binary_director<tag::big_word>    
+    {
+        typedef any_binary_director<boost::integer::big, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::big_dword>    
+    {
+        typedef any_binary_director<boost::integer::big, 32> type;
+    };
+
+    // little endian binaries
+    template <>
+    struct extract_binary_director<tag::little_word>    
+    {
+        typedef any_binary_director<boost::integer::little, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::little_dword>    
+    {
+        typedef any_binary_director<boost::integer::little, 32> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <>
+    struct extract_binary_director<tag::qword>    
+    {
+        typedef any_binary_director<boost::integer::native, 64> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::big_qword>    
+    {
+        typedef any_binary_director<boost::integer::big, 64> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::little_qword>    
+    {
+        typedef any_binary_director<boost::integer::little, 64> type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a binary literal tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_binary_lit_director;
+
+    // native endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::byte, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 8> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::word, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 32> type;
+    };
+
+    // big endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_word, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 32> type;
+    };
+
+    // little endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_word, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 32> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <typename T>
+    struct extract_binary_lit_director<tag::qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 64> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 64> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 64> type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // binary meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    // literals: 10, 10L, 10LL
+    struct int_binary_meta_grammar
+      : meta_grammar::compose_empty<
+            proto::if_<
+                is_int_lit_tag<proto::_arg, karma::domain>()
+            >,
+            karma::domain,
+            mpl::identity<extract_literal_bin_director<mpl::_> >
+        >
+    {
+    };
+
+    struct binary_meta_grammar  
+      : proto::or_<
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_binary_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain, 
+                mpl::identity<extract_binary_director<mpl::_> > 
+            >,
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_binary_tag<proto::_arg, karma::domain>()
+                    >,
+                    int_binary_meta_grammar
+                >,
+                karma::domain,
+                mpl::identity<extract_binary_lit_director<mpl::_, mpl::_> >
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, binary_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, binary_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<binary_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/char.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/char.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0547PM)
+#define BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0547PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/char/char.hpp>
+#include <boost/spirit/home/karma/char/space.hpp>
+#include <boost/spirit/home/karma/char/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/char/char.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/char/char.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,323 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)
+#define BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/detail/to_narrow.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  any_char 
+    //      generates a single character from the associated parameter
+    //      
+    //      Note: this generator has to have an associated parameter
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_char
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef Char type;
+        };
+
+        // any_char has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const&, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            detail::generate_to(sink, param);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return true;
+        }
+
+        // this any_char has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, char__not_usable_without_parameter, ());
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "any-char";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  literal_char 
+    //      generates a single character given by a literal it was initialized
+    //      from
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct literal_char 
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // any_char has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            detail::generate_to(sink, fusion::at_c<0>(component.elements));
+            karma::delimit(sink, d);             // always do post-delimiting 
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("'")
+                + spirit::detail::to_narrow_char(
+                    fusion::at_c<0>(component.elements))
+                + '\'';
+        }
+    };
+                
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  lazy_char 
+    //      generates a single character given by a functor it was initialized 
+    //      from
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    struct lazy_char 
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // any_char has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            detail::generate_to(sink, 
+                fusion::at_c<0>(component.elements)(unused, ctx));
+            karma::delimit(sink, d);             // always do post-delimiting 
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "char";
+        }
+    };
+                
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  lower and upper case variants of any_char with an associated parameter
+    //      note: this generator has to have a parameter associated
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char, typename Tag>
+    struct case_any_char 
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef Char type;
+        };
+
+        typedef typename Tag::char_set char_set;
+        typedef typename Tag::char_class char_class_;
+
+        // case_any_char has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            using spirit::char_class::convert;
+            Char p = convert<char_set>::to(char_class_(), param);
+            detail::generate_to(sink, p);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return true;
+        }
+
+        // this case_any_char has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, char__not_usable_without_parameter, ());
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            std::string result;
+            result = std::string("any-") + 
+                spirit::char_class::what<char_set>::is(char_class_()) + 
+                "case-char";
+            return result;
+        }
+    };
+    
+}}}  // namespace boost::spirit::karma
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case and upper_case any_char and literal_char generators
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::literal_char<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        char_type;
+        typedef fusion::vector<char_type> vector_type;
+
+        typedef component<
+            karma::domain, karma::literal_char<Char>, vector_type> 
+        type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+            
+            char_type ch = fusion::at_c<0>(elements);
+            vector_type v(char_set::tolower(ch));
+            return type(v);
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::literal_char<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        char_type;
+        typedef fusion::vector<char_type> vector_type;
+
+        typedef 
+            component<karma::domain, karma::literal_char<Char>, vector_type> 
+        type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+            
+            char_type ch = fusion::at_c<0>(elements);
+            vector_type v(char_set::toupper(ch));
+            return type(v);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case and upper case_any_char conversions
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::any_char<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+        
+        typedef component<
+            karma::domain, karma::case_any_char<Char, key_tag>, fusion::nil> 
+        type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::any_char<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+        
+        typedef component<
+            karma::domain, karma::case_any_char<Char, key_tag>, fusion::nil> 
+        type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+}}}   // namespace boost::spirit::traits
+
+#endif // !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)
Added: trunk/boost/spirit/home/karma/char/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/char/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,230 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_21_2007_0742AM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_21_2007_0742AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a character literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename CharSet>
+    struct is_char_tag<
+            spirit::char_class::key<CharSet, char_class::tag::space>,
+            karma::domain
+        >
+      : mpl::true_
+    {};
+}}
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forward declarations
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_char;
+
+    template <typename Char>
+    struct literal_char;
+
+    struct lazy_char;
+
+    template <typename Tag, typename Char>
+    struct any_space_char;
+
+    template <typename Tag, typename Char>
+    struct literal_space_char;
+
+    struct char_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a character literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_literal_char_director;
+
+    template <typename T>
+    struct extract_literal_char_director<tag::char_, T>
+    {
+        typedef literal_char<T> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::wchar, T>
+    {
+        typedef literal_char<wchar_t> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::lit, T>
+    {
+        typedef literal_char<T> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::wlit, T>
+    {
+        typedef literal_char<wchar_t> type;
+    };
+
+    template <typename CharSet, typename T>
+    struct extract_literal_char_director<
+        spirit::char_class::key<CharSet, char_class::tag::space>, T
+    >
+    {
+        typedef
+            spirit::char_class::key<CharSet, char_class::tag::space>
+        key_type;
+        typedef literal_space_char<key_type, T> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a plain character type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_any_char_director;
+
+    template <>
+    struct extract_any_char_director<tag::char_>
+    {
+        typedef any_char<char> type;
+    };
+
+    template <>
+    struct extract_any_char_director<tag::wchar>
+    {
+        typedef any_char<wchar_t> type;
+    };
+
+    template <typename CharSet>
+    struct extract_any_char_director<
+        spirit::char_class::key<CharSet, char_class::tag::space>
+    >
+    {
+        typedef typename CharSet::char_type char_type;
+        typedef
+            spirit::char_class::key<CharSet, char_class::tag::space>
+        key_type;
+        typedef any_space_char<key_type, char_type> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // char generator meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+
+    // literals: 'x', L'x'
+    struct char_literal_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                karma::domain, char, literal_char<char> 
+            >,
+            meta_grammar::terminal_rule<
+                karma::domain, wchar_t, literal_char<wchar_t> 
+            >
+        >
+    {
+    };
+
+    // literals: 'x', L'x'
+    struct basic_char_literal_meta_grammar
+      : proto::or_<
+            proto::terminal<char>,
+            proto::terminal<wchar_t>
+        >
+    {
+    };
+
+    // char_, wchar, space
+    // char_('x'), char_(L'x'), wchar('x'), wchar(L'x'), space(' ')
+    struct char_meta_grammar1
+      : proto::or_<
+            // char_, wchar, space
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_char_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain,
+                mpl::identity<extract_any_char_director<mpl::_> >
+            >,
+            // char_('x'), wchar(L'x'), space(' ')
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_char_tag<proto::_arg, karma::domain>()
+                    >,
+                    basic_char_literal_meta_grammar
+                >,
+                karma::domain,
+                mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
+            >,
+            // lit('x'), wlit('x')
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_lit_tag<proto::_arg, karma::domain>()
+                    >,
+                    basic_char_literal_meta_grammar
+                >,
+                karma::domain,
+                mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
+            >,
+            // char_(val('y'))
+            meta_grammar::function1_rule<
+                karma::domain, tag::char_, lazy_char
+            >
+        >
+    {
+    };
+
+    // main char_meta_grammar
+    struct char_meta_grammar
+      : proto::or_<
+            char_literal_meta_grammar,
+            char_meta_grammar1
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr,
+        typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr,
+        typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
+      : mpl::identity<char_meta_grammar>
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/char/space.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/char/space.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,116 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_SPACE_MAR_06_2007_0934PM)
+#define BOOST_SPIRIT_KARMA_SPACE_MAR_06_2007_0934PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/detail/to_narrow.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/spirit/home/support/standard.hpp>
+#include <boost/spirit/home/support/standard_wide.hpp>
+
+namespace boost { namespace spirit { namespace karma 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  space 
+    //      generates a single character from the associated parameter
+    //      
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename Char>
+    struct any_space_char
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef Char type;
+        };
+
+        typedef typename Tag::char_set char_set;
+        typedef typename Tag::char_class char_class_;
+
+        // space has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& ch) 
+        {
+            using spirit::char_class::classify;
+            BOOST_ASSERT(classify<char_set>::is(char_class_(), ch));
+            detail::generate_to(sink, ch);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return true;
+        }
+
+        // this space has no parameter attached, just generate a single ' '
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator& sink, Context&, 
+            Delimiter const& d, unused_type) 
+        {
+            detail::generate_to(sink, ' ');     // generate a single space
+            karma::delimit(sink, d);            // always do post-delimiting 
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "any-space";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  space(...)
+    //      generates a single space character given by a literal it was 
+    //      initialized from
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename Char>
+    struct literal_space_char
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // any_char has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            detail::generate_to(sink, fusion::at_c<0>(component.elements));
+            karma::delimit(sink, d);             // always do post-delimiting 
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("space('")
+                + spirit::detail::to_narrow_char(
+                    fusion::at_c<0>(component.elements))
+                + "')";
+        }
+    };
+
+}}}  // namespace boost::spirit::karma
+
+#endif // !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)
Added: trunk/boost/spirit/home/karma/delimit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/delimit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,35 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DELIMIT_FEB_20_2007_1208PM)
+#define BOOST_SPIRIT_KARMA_DELIMIT_FEB_20_2007_1208PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Do delimiting. This is equivalent to p << d. The function is a
+    //  no-op if spirit::unused is passed as the delimiter-generator.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Delimiter>
+    inline void delimit(OutputIterator& sink, Delimiter const& d)
+    {
+        Delimiter::director::generate(d, sink, unused, unused, unused);
+    }
+
+    template <typename OutputIterator>
+    inline void delimit(OutputIterator&, unused_type)
+    {
+    }
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/karma/detail/generate_to.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/generate_to.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,58 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DETAIL_EXTRACT_FROM_FEB_20_2007_0417PM)
+#define BOOST_SPIRIT_KARMA_DETAIL_EXTRACT_FROM_FEB_20_2007_0417PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  These utility functions insert the given parameter into the supplied 
+    //  output iterator.
+    //  If the parameter is spirit's unused_type, this is a no_op.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Parameter, typename Tag>
+    inline bool 
+    generate_to(OutputIterator& sink, Parameter const& p, Tag)
+    {
+        typedef typename Tag::char_set char_set;
+        typedef typename Tag::char_class char_class;
+        
+        *sink = spirit::char_class::convert<char_set>::to(char_class(), p);
+        ++sink;
+        return true;
+    }
+
+    template <typename OutputIterator, typename Parameter>
+    inline bool 
+    generate_to(OutputIterator& sink, Parameter const& p, unused_type = unused)
+    {
+        *sink = p;
+        ++sink;
+        return true;
+    }
+
+    template <typename OutputIterator, typename Tag>
+    inline bool generate_to(OutputIterator& sink, unused_type, Tag)
+    {
+        return true;
+    }
+    
+    template <typename OutputIterator>
+    inline bool generate_to(OutputIterator& sink, unused_type)
+    {
+        return true;
+    }
+    
+}}}}   // namespace boost::spirit::karma::detail
+
+#endif  // KARMA_CORE_DETAIL_INSERT_TO_HPP
Added: trunk/boost/spirit/home/karma/detail/ostream_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/ostream_iterator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,57 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_OSTREAM_ITERATOR_MAY_26_2007_1016PM)
+#define BOOST_SPIRIT_KARMA_OSTREAM_ITERATOR_MAY_26_2007_1016PM
+
+#include <iterator>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  We need our own implementation of an ostream_iterator just to be able
+    //  to access the wrapped ostream, which is necessary for the 
+    //  stream_director, where we must generate the output using the original
+    //  ostream to retain possibly registered facets.
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename T, typename Elem = char, 
+        typename Traits = std::char_traits<Elem> 
+    >
+    class ostream_iterator 
+      : public std::iterator<std::output_iterator_tag, void, void, void, void>
+    {
+    public:
+        typedef Elem char_type;
+        typedef Traits traits_type;
+        typedef std::basic_ostream<Elem, Traits> ostream_type;
+        typedef ostream_iterator<T, Elem, Traits> self_type;
+        
+        ostream_iterator(ostream_type& os_, Elem const* delim_ = 0)
+          : os(&os_), delim(delim_) {}
+
+        self_type& operator= (T const& val)
+        {
+            *os << val;
+            if (0 != delim)
+                *os << delim;
+            return *this;
+        }
+
+        self_type& operator*() { return *this; }
+        self_type& operator++() { return *this; }
+        self_type operator++(int) { return *this; }
+
+        ostream_type& get_ostream() { return *os; }
+        
+    protected:
+        ostream_type *os;
+        Elem const* delim;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/detail/output_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/output_iterator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,340 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_OUTPUT_ITERATOR_MAY_26_2007_0506PM)
+#define BOOST_SPIRIT_KARMA_OUTPUT_ITERATOR_MAY_26_2007_0506PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <iterator>
+#include <vector>
+#include <algorithm>
+
+#include <boost/spirit/home/karma/detail/ostream_iterator.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This class is used to count the umber of characters streamed into the 
+    //  output.
+    ///////////////////////////////////////////////////////////////////////////
+    class counting_sink 
+    {
+    public:
+        counting_sink() : count(0) {}
+        
+        void init(std::size_t count_) { count = count_; }
+        void tidy() { count = 0; }
+        
+        void output() { ++count; }
+        std::size_t get_count() const { return count; }
+
+    private:
+        std::size_t count;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  The following classes are used to intercept the output into a buffer
+    //  allowing to do things like alignment, character escaping etc.
+    //
+    //  We need to use virtual functions because output_iterators do not have
+    //  an associated value_type. The type of the buffer elements is available
+    //  at insertion time only (and not at buffer creation time).
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator>
+    struct abstract_container
+    {
+        virtual ~abstract_container() {}
+        virtual void output(void const *item) = 0;
+        virtual void copy(OutputIterator& sink) = 0;
+        virtual std::size_t buffer_size() = 0;
+    };
+    
+    template <typename OutputIterator, typename T>
+    class concrete_container : public abstract_container<OutputIterator>
+    {
+    public:
+        concrete_container(std::size_t size)
+        { 
+            buffer.reserve(size); 
+        }
+        ~concrete_container() {}
+
+        void output(void const *item)
+        {
+            buffer.push_back(*static_cast<T const*>(item));
+        }
+        void copy(OutputIterator& sink)
+        {
+            std::copy(buffer.begin(), buffer.end(), sink);
+        }
+        std::size_t buffer_size()
+        {
+            return buffer.size();
+        }
+    
+    private:
+        std::vector<T> buffer;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator>
+    class buffer_sink 
+    {
+    public:
+        buffer_sink()
+          : width(0), buffer(0) 
+        {}
+        
+        ~buffer_sink() 
+        { 
+            delete buffer; 
+        }
+        
+        void init(std::size_t width_) { width = width_; }
+        void tidy() { delete buffer; buffer = 0; width = 0; }
+        
+        template <typename T>
+        void output(T const& value)
+        {
+            if (0 == buffer)
+            {
+                typedef concrete_container<OutputIterator, T> container;
+                buffer = new container(width);
+            }
+            buffer->output(&value);
+        }
+        
+        void copy(OutputIterator& sink) const 
+        { 
+            if (buffer) 
+                buffer->copy(sink); 
+        }
+        
+        std::size_t buffer_size() const 
+        { 
+            return buffer ? buffer->buffer_size() : 0; 
+        }
+
+    private:        
+        std::size_t width;
+        abstract_container<OutputIterator> *buffer;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  forward declaration only
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator> struct enable_counting;
+    template <typename OutputIterator> struct enable_buffering;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Karma uses a output iterator wrapper for all output operations. This
+    //  is necessary to avoid the dreaded 'scanner business' problem, i.e. the
+    //  dependency of rules and grammars on the used output iterator. 
+    //
+    //  By default the user supplied output iterator is wrapped inside an 
+    //  instance of this internal output_iterator class. 
+    //
+    //  This output_iterator class normally just forwards to the embedded user
+    //  supplied iterator. But it is possible to enable additional functionality
+    //  on demand, such as counting, buffering, and position tracking.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Enable = void>
+    class output_iterator
+    {
+    private:
+        enum output_mode 
+        {
+            output_characters = 0,    // just hand through character
+            count_characters = 1,     // additionally count characters
+            buffer_characters = 2     // buffer all characters, no output
+        };
+        
+        struct output_proxy 
+        {
+            output_proxy(output_iterator& parent) 
+              : parent(parent) 
+            {}
+            
+            template <typename T> 
+            output_proxy& operator=(T const& value) 
+            {
+                parent.output(value);
+                return *this; 
+            }
+
+        private:
+            output_iterator& parent;
+        };
+        
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+private:
+        friend struct enable_counting<output_iterator>;
+        friend struct enable_buffering<output_iterator>;
+#else
+public:
+#endif
+        // functions related to counting
+        void enable_counting(std::size_t count = 0)
+        {
+            count_data.init(count);
+            mode = output_mode(mode | count_characters);
+        }
+        void disable_counting()
+        {
+            mode = output_mode(mode & ~count_characters);
+        }
+        void reset_counting()
+        {
+            count_data.tidy();
+        }
+        
+        // functions related to buffering
+        void enable_buffering(std::size_t width = 0)
+        {
+            buffer_data.init(width);
+            mode = output_mode(mode | buffer_characters);
+        }
+        void disable_buffering()
+        {
+            mode = output_mode(mode & ~buffer_characters);
+        }
+        void reset_buffering()
+        {
+            buffer_data.tidy();
+        }
+        
+    public:
+        typedef std::output_iterator_tag iterator_category;
+        typedef void value_type;
+        typedef void difference_type;
+        typedef void pointer;
+        typedef void reference;
+
+        output_iterator(OutputIterator& sink_)
+          : sink(sink_), mode(output_characters)
+        {}
+
+        output_proxy operator*() { return output_proxy(*this); }
+        output_iterator& operator++() { ++sink; return *this; } 
+        output_iterator& operator++(int) { sink++; return *this; }
+
+        template <typename T> 
+        void output(T const& value) 
+        { 
+            if (mode & count_characters)    // count characters, if appropriate
+                count_data.output();
+
+            if (mode & buffer_characters)   // buffer output, if appropriate
+                buffer_data.output(value);
+            else
+                *sink = value; 
+        }
+
+        // functions related to counting
+        std::size_t count() const
+        {
+            return count_data.get_count();
+        }
+        
+        // functions related to buffering
+        std::size_t buffer_size() const
+        {
+            return buffer_data.buffer_size();
+        }
+        void buffer_copy()
+        {
+            buffer_data.copy(sink);
+        }
+        
+    protected:
+        // this is the wrapped user supplied output iterator
+        OutputIterator& sink;
+
+    private:
+        // these are the hooks providing optional functionality
+        counting_sink count_data;                   // for counting
+        buffer_sink<OutputIterator> buffer_data;    // for buffering
+        output_mode mode;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Elem, typename Traits>
+    class output_iterator<ostream_iterator<T, Elem, Traits> >
+      : public output_iterator<ostream_iterator<T, Elem, Traits>, int>
+    {
+    private:
+        typedef 
+            output_iterator<ostream_iterator<T, Elem, Traits>, int> 
+        base_type;
+        typedef ostream_iterator<T, Elem, Traits> base_iterator_type;
+	    typedef std::basic_ostream<Elem, Traits> ostream_type;
+        
+    public:
+        output_iterator(base_iterator_type& sink)
+          : base_type(sink)
+        {}
+        
+        ostream_type& get_ostream() { return this->sink.get_ostream(); }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  Helper class for exception safe enabling of character counting in the
+    //  output iterator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator>
+    struct enable_counting
+    {
+        enable_counting(OutputIterator& sink_, std::size_t count = 0)
+          : sink(sink_)
+        {
+            sink.enable_counting(count);
+        }
+        ~enable_counting()
+        {
+            sink.disable_counting();
+            sink.reset_counting();
+        }
+        
+        void disable()
+        {
+            sink.disable_counting();
+        }
+
+        OutputIterator& sink;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  Helper class for exception safe enabling of character buffering in the
+    //  output iterator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator>
+    struct enable_buffering
+    {
+        enable_buffering(OutputIterator& sink_, std::size_t width = 0)
+          : sink(sink_)
+        {
+            sink.enable_buffering(width);
+        }
+        ~enable_buffering()
+        {
+            sink.disable_buffering();
+            sink.reset_buffering();
+        }
+        
+        void disable()
+        {
+            sink.disable_buffering();
+        }
+        
+        OutputIterator& sink;
+    };
+    
+}}}}
+
+#endif 
+
Added: trunk/boost/spirit/home/karma/detail/string_generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/string_generate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,85 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_STRING_GENERATE_FEB_23_2007_1232PM)
+#define BOOST_SPIRIT_KARMA_STRING_GENERATE_FEB_23_2007_1232PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <string>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  generate a string given by a pointer 
+    template <typename OutputIterator, typename Char>
+    inline bool 
+    string_generate(OutputIterator& sink, Char const* str, unused_type = unused)
+    {
+        Char ch;
+        for (/**/; !!(ch = *str); ++str)
+            detail::generate_to(sink, ch);
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  generate a string given by a std::string
+    template <typename OutputIterator, typename Char>
+    inline bool 
+    string_generate(OutputIterator& sink, std::basic_string<Char> const& str,
+        unused_type = unused)
+    {
+        typedef std::basic_string<Char> string_type;
+        
+        typename string_type::const_iterator end = str.end();
+        for (typename string_type::const_iterator it = str.begin(); 
+             it != end; ++it)
+        {
+            detail::generate_to(sink, *it);
+        }
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  generate a string given by a pointer, converting according using a 
+    //  given character class tag
+    template <typename OutputIterator, typename Char, typename Tag>
+    inline bool 
+    string_generate(OutputIterator& sink, Char const* str, Tag tag)
+    {
+        Char ch;
+        for (/**/; !!(ch = *str); ++str) 
+        {
+            detail::generate_to(sink, ch, tag);
+        }
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  generate a string given by a std::string, converting according using a 
+    //  given character class tag
+    template <typename OutputIterator, typename Char, typename Tag>
+    inline bool 
+    string_generate(OutputIterator& sink, std::basic_string<Char> const& str, 
+        Tag tag)
+    {
+        typedef std::basic_string<Char> string_type;
+        
+        typename string_type::const_iterator end = str.end();
+        for (typename string_type::const_iterator it = str.begin(); 
+             it != end; ++it)
+        {
+            detail::generate_to(sink, *it, tag);
+        }
+        return true;
+    }
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/directive.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,36 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DIRECTIVE_FEB_21_2007_0833PM)
+#define BOOST_SPIRIT_KARMA_DIRECTIVE_FEB_21_2007_0833PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  directives related to alignment 
+//  left_align[...], right_align[...], center[...]
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/home/karma/directive/left_alignment.hpp>
+#include <boost/spirit/home/karma/directive/right_alignment.hpp>
+#include <boost/spirit/home/karma/directive/center_alignment.hpp>
+#include <boost/spirit/home/karma/directive/alignment_meta_grammar.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//  directives related to character case
+//  lower[...] and upper[...]
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/home/karma/directive/case_meta_grammar.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//  directives related to delimiting generators 
+//  delimit[...] and verbatim[...]
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/home/karma/directive/verbatim.hpp>
+#include <boost/spirit/home/karma/directive/delimit.hpp>
+#include <boost/spirit/home/karma/directive/delimiter_meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/directive/alignment_meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/alignment_meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,171 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_ALIGNMENT_META_GRAMMAR_FEB_21_2007_0826PM)
+#define BOOST_SPIRIT_KARMA_ALIGNMENT_META_GRAMMAR_FEB_21_2007_0826PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct main_meta_grammar;
+    
+    struct simple_left_aligment;
+    struct simple_right_aligment;
+    struct simple_center_aligment;
+    
+    struct width_left_aligment;
+    struct width_right_aligment;
+    struct width_center_aligment;
+    
+    struct padding_left_aligment;
+    struct padding_right_aligment;
+    struct padding_center_aligment;
+    
+    struct full_left_aligment;
+    struct full_right_aligment;
+    struct full_center_aligment;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  left, right and center directive meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+    struct simple_align_directive_meta_grammar 
+      : proto::or_<
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::subscript, simple_left_aligment,
+                proto::terminal<tag::left_align>, main_meta_grammar
+            >,
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::subscript, simple_right_aligment,
+                proto::terminal<tag::right_align>, main_meta_grammar
+            >,
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::subscript, simple_center_aligment,
+                proto::terminal<tag::center>, main_meta_grammar
+            >
+        >
+    {};
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  matches alignment directives defining the width only: 
+    //  left_align(width)[...], right_align(width)[...], center(width)[...]
+    ///////////////////////////////////////////////////////////////////////////
+    struct width_align_directive_meta_grammar 
+      : proto::or_<
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::left_align, width_left_aligment,
+                proto::terminal<int>, main_meta_grammar
+            >,
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::right_align, width_right_aligment,
+                proto::terminal<int>, main_meta_grammar
+            >,
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::center, width_center_aligment,
+                proto::terminal<int>, main_meta_grammar
+            >
+        >
+    {};
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  matches alignment directives defining the padding generator only: 
+    //  left_align(padding)[...], right_align(padding)[...], center(padding)[...]
+    ///////////////////////////////////////////////////////////////////////////
+    struct padding_align_directive_meta_grammar 
+      : proto::or_<
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::left_align, padding_left_aligment,
+                main_meta_grammar, main_meta_grammar
+            >,
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::right_align, padding_right_aligment,
+                main_meta_grammar, main_meta_grammar
+            >,
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::center, padding_center_aligment,
+                main_meta_grammar, main_meta_grammar
+            >
+        >
+    {};
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  matches full alignment directives: left_align(width, padding)[...],
+    //  right_align(width, padding)[...], center(width, padding)[...]
+    ///////////////////////////////////////////////////////////////////////////
+    struct full_align_directive_meta_grammar 
+      : proto::or_<
+            meta_grammar::subscript_function2_rule<
+                karma::domain, tag::left_align, full_left_aligment,
+                proto::terminal<int>, main_meta_grammar, main_meta_grammar
+            >,
+            meta_grammar::subscript_function2_rule<
+                karma::domain, tag::right_align, full_right_aligment,
+                proto::terminal<int>, main_meta_grammar, main_meta_grammar
+            >,
+            meta_grammar::subscript_function2_rule<
+                karma::domain, tag::center, full_center_aligment,
+                proto::terminal<int>, main_meta_grammar, main_meta_grammar
+            >
+        >
+    {};
+    
+    // main alignment_directive_meta_grammar
+    struct alignment_directive_meta_grammar
+      : proto::or_<
+            simple_align_directive_meta_grammar,
+            width_align_directive_meta_grammar,
+            padding_align_directive_meta_grammar,
+            full_align_directive_meta_grammar
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////  
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, alignment_directive_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                    proto::matches<Expr, alignment_directive_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<alignment_directive_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/directive/case_meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/case_meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,133 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_CASE_META_GRAMMAR_FEB_21_2007_0826PM)
+#define BOOST_SPIRIT_KARMA_CASE_META_GRAMMAR_FEB_21_2007_0826PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/spirit/home/support/standard.hpp>
+#include <boost/spirit/home/support/standard_wide.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct main_meta_grammar;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  lower and upper directive meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+    struct lower_case_directive_meta_grammar 
+      : meta_grammar::deep_directive_meta_grammar<
+            spirit::char_class::lower_case_tag<proto::_>,
+            main_meta_grammar
+        >
+    {};
+
+    struct upper_case_directive_meta_grammar  
+      : meta_grammar::deep_directive_meta_grammar<
+            spirit::char_class::upper_case_tag<proto::_>,
+            main_meta_grammar
+        >
+    {};
+
+    // main directive_meta_grammar
+    struct directive_meta_grammar
+      : proto::or_<
+            lower_case_directive_meta_grammar,
+            upper_case_directive_meta_grammar
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////  
+    template <typename Expr>
+    struct is_valid_expr<Expr,
+        typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr,
+        typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
+      : mpl::identity<directive_meta_grammar>
+    {
+    };
+    
+}}}
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The following specializations for the add_modifier template are added
+    //  to allow for special handling of the lower[] and upper[] directives
+    //  which are mutually exclusive. Since the first of these directives 
+    //  added to the modifier corresponds to the outermost one in the generator
+    //  expression, we just ignore the request to add a tag if one of the two
+    //  has been already added.
+    template <typename Modifier, typename Tag>
+    struct add_modifier<Modifier, spirit::char_class::lower_case_tag<Tag> >
+    {
+        // add the new tag to the modifier (if it isn't already)
+        typedef spirit::char_class::upper_case_tag<Tag> reciprocal_tag;
+        typedef spirit::char_class::lower_case_tag<Tag> tag;
+
+        typedef typename
+            mpl::if_<
+                mpl::or_<
+                    is_member_of_modifier<Modifier, reciprocal_tag>,
+                    is_member_of_modifier<Modifier, tag>
+                >,
+                Modifier,
+                modifier<Modifier, tag>
+            >::type 
+        type;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Modifier, typename Tag>
+    struct add_modifier<Modifier, spirit::char_class::upper_case_tag<Tag> >
+    {
+        // add the new tag to the modifier (if it isn't already)
+        typedef spirit::char_class::lower_case_tag<Tag> reciprocal_tag;
+        typedef spirit::char_class::upper_case_tag<Tag> tag;
+        
+        typedef typename
+            mpl::if_<
+                mpl::or_<
+                    is_member_of_modifier<Modifier, reciprocal_tag>,
+                    is_member_of_modifier<Modifier, tag>
+                >,
+                Modifier,
+                modifier<Modifier, tag>
+            >::type 
+        type;
+    };
+    
+}}
+
+#endif
Added: trunk/boost/spirit/home/karma/directive/center_alignment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/center_alignment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,231 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_CENTER_ALIGNMENT_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_CENTER_ALIGNMENT_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp>
+#include <boost/lexical_cast.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The BOOST_KARMA_DEFAULT_FIELD_LENGTH specifies the default field length 
+//  to be used for padding.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_KARMA_DEFAULT_FIELD_LENGTH)
+#define BOOST_KARMA_DEFAULT_FIELD_LENGTH 10
+#endif
+
+namespace boost { namespace spirit { namespace karma 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The simple center alignment directive is used for center[...] 
+    //  generators. It uses default values for the generated width (defined via
+    //  the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct simple_center_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::argument1<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::center_generate(sink, ctx, d, param, 
+                argument1(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, 
+                spirit::as_component(karma::domain(), ' '));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "center[";
+
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            director;
+
+            result += director::what(spirit::argument1(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The center alignment with width directive, is used for generators
+    //  like center(width)[...]. It uses a default value for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct width_center_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::center_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), ' ');
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "center(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The center alignment directive with padding, is used for generators like
+    //  center(padding)[...], where padding is a arbitrary generator 
+    //  expression. It uses a default value for the generated width (defined 
+    //  via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
+    ///////////////////////////////////////////////////////////////////////////
+    struct padding_center_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::center_generate(sink, ctx, d, param, 
+                subject(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, 
+                argument1(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "center(";
+            
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument1(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The full center alignment directive, is used for generators like 
+    //  center(width, padding)[...], where width is a integer value to be 
+    //  used as the field width and padding is a arbitrary generator 
+    //  expression.
+    ///////////////////////////////////////////////////////////////////////////
+    struct full_center_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::center_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), 
+                argument2(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "center(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ", ";
+
+            typedef typename
+                spirit::result_of::argument2<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument2(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+}}} // namespace boost::spirit::karma
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/delimit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/delimit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,126 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DELIMIT_MAR_02_2007_0217PM)
+#define BOOST_SPIRIT_KARMA_DELIMIT_MAR_02_2007_0217PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The delimit_space generator is used for delimit[...] directives.
+    ///////////////////////////////////////////////////////////////////////////
+    struct delimit_space
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::right<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& /*d*/, Parameter const& param) 
+        {
+            //  the delimit_space generator simply dispatches to the embedded 
+            //  generator while supplying a single space as the new delimiter
+            //  to use
+            typedef typename 
+                result_of::right<Component>::type::director
+            director;
+            
+            return director::generate(spirit::right(component), 
+                sink, ctx, spirit::as_component(karma::domain(), ' '), param);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "delimit[";
+
+            typedef typename
+                spirit::result_of::right<Component>::type::director
+            director;
+
+            result += director::what(spirit::right(component));
+            result += "]";
+            return result;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  The delimit_ generator is used for delimit(d)[...] directives.
+    ///////////////////////////////////////////////////////////////////////////
+    struct delimit_
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& /*d*/, Parameter const& param) 
+        {
+            //  the delimit generator simply dispatches to the embedded 
+            //  generator while supplying it's argument as the new delimiter
+            //  to use
+            typedef typename 
+                spirit::result_of::subject<Component>::type::director
+            director;
+            
+            return director::generate(spirit::subject(component), sink, ctx, 
+                spirit::as_component(
+                    karma::domain(), spirit::argument1(component)), 
+                param);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "delimit(";
+            
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            delimiter;
+            
+            result += delimiter::what(spirit::argument1(component));
+            result +=")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/directive/delimiter_meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/delimiter_meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,87 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DELIMITER_META_GRAMMAR_FEB_21_2007_0826PM)
+#define BOOST_SPIRIT_KARMA_DELIMITER_META_GRAMMAR_FEB_21_2007_0826PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct main_meta_grammar;
+    
+    struct delimit_;
+    struct delimit_space;
+    struct verbatim;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  delimit and verbatim directive meta-grammars
+    //  delimit[...], delimit(delimiter)[...] and verbatim[...]
+    ///////////////////////////////////////////////////////////////////////////
+    struct delimiter_directive_meta_grammar
+      : proto::or_<
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::subscript, verbatim,
+                proto::terminal<tag::verbatim>, main_meta_grammar
+            >,
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::subscript, delimit_space,
+                proto::terminal<tag::delimit>, main_meta_grammar
+            >,
+            meta_grammar::subscript_function1_rule<
+                karma::domain, tag::delimit, delimit_,
+                main_meta_grammar, main_meta_grammar
+            >
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////  
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, delimiter_directive_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, delimiter_directive_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<delimiter_directive_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,81 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_CENTER_ALIGNMENT_GENERATE_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_CENTER_ALIGNMENT_GENERATE_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The center_generate template function is used for all the different
+    //  flavors of the center[] directive. 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Context, typename Delimiter, 
+        typename Parameter, typename Embedded, typename Padding>
+    inline static bool 
+    center_generate(OutputIterator& sink, Context& ctx, 
+        Delimiter const& d, Parameter const& param, Embedded const& e, 
+        unsigned int const width, Padding const& p) 
+    {
+        // make sure all generator parameters are valid
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Embedded>::value), 
+            embedded_is_not_convertible_to_a_generator, (Context, Embedded));
+
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Padding>::value), 
+            padding_is_not_convertible_to_a_generator, (Context, Padding));
+            
+        typedef 
+            typename result_of::as_component<karma::domain, Embedded>::type 
+        embedded;
+        typedef 
+            typename result_of::as_component<karma::domain, Padding>::type 
+        padding;
+        
+        // wrap the given output iterator to allow left padding
+        detail::enable_buffering<OutputIterator> buffering(sink, width);
+        
+        // first generate the embedded output 
+        embedded ec = spirit::as_component(karma::domain(), e);
+        typedef typename embedded::director director;
+        bool r = director::generate(ec, sink, ctx, d, param);
+
+        buffering.disable();    // do not perform buffering any more
+        
+        // generate the left padding
+        detail::enable_counting<OutputIterator> 
+            counting(sink, (sink.buffer_size() + width) / 2);
+
+        padding pc = spirit::as_component(karma::domain(), p);
+        typedef typename padding::director padding_director;
+        while (r && sink.count() < width) 
+            r = padding_director::generate(pc, sink, ctx, unused, unused);
+
+        if (r) {
+            // copy the embedded output to the target output iterator
+            sink.buffer_copy();
+        
+            // generate the right padding
+            std::size_t const max_count = width + (width - sink.buffer_size()) / 2;
+            while (r && sink.count() < max_count) 
+                r = padding_director::generate(pc, sink, ctx, unused, unused);
+        }
+        return r;
+    }
+
+}}}}   // namespace boost::spirit::karma::detail
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/detail/left_alignment_generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/detail/left_alignment_generate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,67 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_GENERATE_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_GENERATE_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The left_align_generate template function is used for all the different
+    //  flavors of the left_align[] directive. 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Context, typename Delimiter, 
+        typename Parameter, typename Embedded, typename Padding>
+    inline static bool 
+    left_align_generate(OutputIterator& sink, Context& ctx, 
+        Delimiter const& d, Parameter const& param, Embedded const& e, 
+        unsigned int const width, Padding const& p) 
+    {
+        // make sure all generator parameters are valid
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Embedded>::value), 
+            embedded_is_not_convertible_to_a_generator, (Context, Embedded));
+
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Padding>::value), 
+            padding_is_not_convertible_to_a_generator, (Context, Padding));
+            
+        typedef 
+            typename result_of::as_component<karma::domain, Embedded>::type 
+        embedded;
+        typedef 
+            typename result_of::as_component<karma::domain, Padding>::type 
+        padding;
+
+        // wrap the given output iterator to allow counting
+        detail::enable_counting<OutputIterator> counting(sink);
+        
+        // first generate the underlying output 
+        embedded ec = spirit::as_component(karma::domain(), e);
+        typedef typename embedded::director director;
+        bool r = director::generate(ec, sink, ctx, d, param);
+
+        // pad the output until the max width is reached
+        padding pc = spirit::as_component(karma::domain(), p);
+        while(r && sink.count() < width) {
+            typedef typename padding::director padding_director;
+            r = padding_director::generate(pc, sink, ctx, unused, unused);
+        }
+        return r;
+    }
+
+}}}}   // namespace boost::spirit::karma::detail
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/detail/right_alignment_generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/detail/right_alignment_generate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,75 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_GENERATE_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_GENERATE_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The right_align_generate template function is used for all the 
+    //  different flavors of the right_align[] directive. 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Context, typename Delimiter, 
+        typename Parameter, typename Embedded, typename Padding>
+    inline static bool 
+    right_align_generate(OutputIterator& sink, Context& ctx, 
+        Delimiter const& d, Parameter const& param, Embedded const& e, 
+        unsigned int const width, Padding const& p) 
+    {
+        // make sure all generator parameters are valid
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Embedded>::value), 
+            embedded_is_not_convertible_to_a_generator, (Context, Embedded));
+
+        BOOST_MPL_ASSERT_MSG(
+            (spirit::traits::is_component<karma::domain, Padding>::value), 
+            padding_is_not_convertible_to_a_generator, (Context, Padding));
+            
+        typedef 
+            typename result_of::as_component<karma::domain, Embedded>::type 
+        embedded;
+        typedef 
+            typename result_of::as_component<karma::domain, Padding>::type 
+        padding;
+        
+        // wrap the given output iterator to allow left padding
+        detail::enable_buffering<OutputIterator> buffering(sink, width);
+    
+        // first generate the embedded output 
+        embedded ec = spirit::as_component(karma::domain(), e);
+        typedef typename embedded::director director;
+        bool r = director::generate(ec, sink, ctx, d, param);
+        
+        buffering.disable();    // do not perform buffering any more
+        
+        // generate the left padding
+        detail::enable_counting<OutputIterator> counting(sink, sink.buffer_size());
+
+        padding pc = spirit::as_component(karma::domain(), p);
+        while(r && sink.count() < width) {
+            typedef typename padding::director padding_director;
+            r = padding_director::generate(pc, sink, ctx, unused, unused);
+        }
+        
+        // copy the embedded output to the target output iterator
+        if (r) 
+            sink.buffer_copy();
+        return r;
+    }
+
+}}}}   // namespace boost::spirit::karma::detail
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/left_alignment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/left_alignment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,230 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/directive/detail/left_alignment_generate.hpp>
+#include <boost/lexical_cast.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The BOOST_KARMA_DEFAULT_FIELD_LENGTH specifies the default field length 
+//  to be used for padding.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_KARMA_DEFAULT_FIELD_LENGTH)
+#define BOOST_KARMA_DEFAULT_FIELD_LENGTH 10
+#endif
+
+namespace boost { namespace spirit { namespace karma 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The simple left alignment directive is used for left_align[...] 
+    //  generators. It uses default values for the generated width (defined via
+    //  the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct simple_left_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute 
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::argument1<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::left_align_generate(sink, ctx, d, param, 
+                argument1(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, ' ');
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "left_align[";
+
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            director;
+
+            result += director::what(spirit::argument1(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The left alignment with width directive, is used for generators
+    //  like left_align(width)[...]. It uses a default value for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct width_left_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::left_align_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), ' ');
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "left_align(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The left alignment directive with padding, is used for generators like
+    //  left_align(padding)[...], where padding is a arbitrary generator 
+    //  expression. It uses a default value for the generated width (defined 
+    //  via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
+    ///////////////////////////////////////////////////////////////////////////
+    struct padding_left_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::left_align_generate(sink, ctx, d, param, 
+                subject(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, 
+                argument1(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "left_align(";
+            
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument1(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The full left alignment directive, is used for generators like 
+    //  left_align(width, padding)[...], where width is a integer value to be 
+    //  used as the field width and padding is a arbitrary generator 
+    //  expression.
+    ///////////////////////////////////////////////////////////////////////////
+    struct full_left_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::left_align_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), 
+                argument2(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "left_align(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ", ";
+
+            typedef typename
+                spirit::result_of::argument2<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument2(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+}}} // namespace boost::spirit::karma
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/right_alignment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/right_alignment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,231 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_FEB_27_2007_1216PM)
+#define BOOST_SPIRIT_KARMA_RIGHT_ALIGNMENT_FEB_27_2007_1216PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/directive/detail/right_alignment_generate.hpp>
+#include <boost/lexical_cast.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The BOOST_KARMA_DEFAULT_FIELD_LENGTH specifies the default field length 
+//  to be used for padding.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_KARMA_DEFAULT_FIELD_LENGTH)
+#define BOOST_KARMA_DEFAULT_FIELD_LENGTH 10
+#endif
+
+namespace boost { namespace spirit { namespace karma 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The simple right alignment directive is used for right_align[...] 
+    //  generators. It uses default values for the generated width (defined via
+    //  the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct simple_right_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::argument1<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::right_align_generate(sink, ctx, d, param, 
+                argument1(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, 
+                spirit::as_component(karma::domain(), ' '));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "right_align[";
+
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            director;
+
+            result += director::what(spirit::argument1(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The right alignment with width directive, is used for generators
+    //  like right_align(width)[...]. It uses a default value for the padding
+    //  generator (always spaces).
+    ///////////////////////////////////////////////////////////////////////////
+    struct width_right_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::right_align_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), ' ');
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "right_align(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The right alignment directive with padding, is used for generators like
+    //  right_align(padding)[...], where padding is a arbitrary generator 
+    //  expression. It uses a default value for the generated width (defined 
+    //  via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
+    ///////////////////////////////////////////////////////////////////////////
+    struct padding_right_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::right_align_generate(sink, ctx, d, param, 
+                subject(component), BOOST_KARMA_DEFAULT_FIELD_LENGTH, 
+                argument1(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "right_align(";
+            
+            typedef typename
+                spirit::result_of::argument1<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument1(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The full right alignment directive, is used for generators like 
+    //  right_align(width, padding)[...], where width is a integer value to be 
+    //  used as the field width and padding is a arbitrary generator 
+    //  expression.
+    ///////////////////////////////////////////////////////////////////////////
+    struct full_right_aligment
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::subject<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            return detail::right_align_generate(sink, ctx, d, param, 
+                subject(component), proto::arg_c<0>(argument1(component)), 
+                argument2(component));
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "right_align(";
+            
+            result += boost::lexical_cast<std::string>(
+                proto::arg_c<0>(argument1(component)));
+            result += ", ";
+
+            typedef typename
+                spirit::result_of::argument2<Component>::type::director
+            padding;
+
+            result += padding::what(spirit::argument2(component));
+            result += ")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+    
+}}} // namespace boost::spirit::karma
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/directive/verbatim.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/verbatim.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,75 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_VERBATIM_MAR_02_2007_0303PM)
+#define BOOST_SPIRIT_KARMA_VERBATIM_MAR_02_2007_0303PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The verbatim generator is used for verbatim[...] directives.
+    ///////////////////////////////////////////////////////////////////////////
+    struct verbatim
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+          : traits::attribute_of<
+                karma::domain,
+                typename result_of::right<Component>::type, 
+                Context
+            >
+        {
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& param) 
+        {
+            //  the verbatim generator simply dispatches to the embedded 
+            //  generator while supplying unused as the new delimiter
+            //  to avoid delimiting down the generator stream
+            typedef typename 
+                spirit::result_of::right<Component>::type::director
+            director;
+            
+            if (director::generate(spirit::right(component), sink, ctx, 
+                    unused, param))
+            {
+                karma::delimit(sink, d);           // always do post-delimiting 
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "verbatim[";
+
+            typedef typename
+                spirit::result_of::right<Component>::type::director
+            director;
+
+            result += director::what(spirit::right(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/domain.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/domain.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_DOMAIN_FEB_20_2007_0943AM)
+#define BOOST_SPIRIT_KARMA_DOMAIN_FEB_20_2007_0943AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct domain 
+    {};
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/generate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,182 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_GENERATE_FEB_20_2007_0959AM)
+#define BOOST_SPIRIT_KARMA_GENERATE_FEB_20_2007_0959AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/meta_grammar.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+
+///////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // normally any skipper can be used with any generator
+    template <typename Generator, typename Delimiter>
+    struct delimiter_is_compatible : mpl::true_
+    {
+    };
+    
+    // If the parser is a rule or a grammar, then the delimiter must be 
+    // convertible to the delimiter used with this rule or grammar. The 
+    // corresponding specializations are defined in the files grammar.hpp and
+    // rule.hpp.
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Expr>
+    inline bool
+    generate(OutputIterator target_sink, Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<karma::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr));
+
+        // wrap user supplied iterator into our own output iterator
+        detail::output_iterator<OutputIterator> sink(target_sink);
+        
+        typedef
+            typename result_of::as_component<karma::domain, Expr>::type
+        component;
+        typedef typename component::director director;
+
+        component c = spirit::as_component(karma::domain(), xpr);
+        return director::generate(c, sink, unused, unused, unused);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Expr, typename Parameter>
+    inline bool
+    generate(OutputIterator target_sink, Expr const& xpr, Parameter const& param)
+    {
+        typedef spirit::traits::is_component<karma::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr, Parameter));
+
+        // wrap user supplied iterator into our own output iterator
+        detail::output_iterator<OutputIterator> sink(target_sink);
+        
+        typedef
+            typename result_of::as_component<karma::domain, Expr>::type
+        component;
+        typedef typename component::director director;
+
+        component c = spirit::as_component(karma::domain(), xpr);
+        return director::generate(c, sink, unused, unused, param);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Expr, typename Delimiter>
+    inline bool
+    generate_delimited(OutputIterator target_sink, Expr const& xpr,
+        Delimiter const& delimiter)
+    {
+        typedef
+            spirit::traits::is_component<karma::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<karma::domain, Delimiter>
+        delimiter_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr, Delimiter));
+
+        BOOST_MPL_ASSERT_MSG(delimiter_is_component::value,
+            delimiter_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr, Delimiter));
+
+        typedef spirit::traits::delimiter_is_compatible<Expr, Delimiter>
+            delimiter_is_compatible;
+            
+        BOOST_MPL_ASSERT_MSG(
+            delimiter_is_compatible::value,
+            delimiter_is_not_compatible_with_generator, 
+            (OutputIterator, Expr, Delimiter));
+        
+        // wrap user supplied iterator into our own output iterator
+        detail::output_iterator<OutputIterator> sink(target_sink);
+        
+        typedef
+            typename result_of::as_component<karma::domain, Expr>::type
+        component;
+        typedef typename component::director director;
+        typedef
+            typename result_of::as_component<karma::domain, Delimiter>::type
+        delim_component;
+
+        component c = spirit::as_component(karma::domain(), xpr);
+        delim_component d = spirit::as_component(karma::domain(), delimiter);
+        return director::generate(c, sink, unused, d, unused);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Expr, typename Parameter,
+        typename Delimiter>
+    inline bool
+    generate_delimited(OutputIterator target_sink, Expr const& xpr,
+        Parameter const& param, Delimiter const& delimiter)
+    {
+        typedef
+            spirit::traits::is_component<karma::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<karma::domain, Delimiter>
+        delimiter_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr, Parameter, Delimiter));
+
+        BOOST_MPL_ASSERT_MSG(delimiter_is_component::value,
+            delimiter_is_not_convertible_to_a_generator, 
+            (OutputIterator, Expr, Parameter, Delimiter));
+
+        typedef spirit::traits::delimiter_is_compatible<Expr, Delimiter>
+            delimiter_is_compatible;
+            
+        BOOST_MPL_ASSERT_MSG(
+            delimiter_is_compatible::value,
+            delimiter_is_not_compatible_with_generator, 
+            (OutputIterator, Expr, Parameter, Delimiter));
+        
+        // wrap user supplied iterator into our own output iterator
+        detail::output_iterator<OutputIterator> sink(target_sink);
+        
+        typedef
+            typename result_of::as_component<karma::domain, Expr>::type
+        component;
+        typedef typename component::director director;
+        typedef
+            typename result_of::as_component<karma::domain, Delimiter>::type
+        delim_component;
+
+        component c = spirit::as_component(karma::domain(), xpr);
+        delim_component d = spirit::as_component(karma::domain(), delimiter);
+        return director::generate(c, sink, unused, d, param);
+    }
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/karma/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_20_2007_0939AM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_20_2007_0939AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/placeholders.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    // Check if Expr is a valid Karma expression
+    template <typename Expr, typename Enable = void>
+    struct is_valid_expr : mpl::false_ {};
+
+    // Return a suitable transform for the given Expr
+    template <typename Expr, typename Enable = void>
+    struct expr_transform;
+
+    struct main_meta_grammar
+      : meta_grammar::if_transform<
+            is_valid_expr<proto::_>(),
+            expr_transform<proto::_> 
+        >
+    {
+    };
+    
+}}}
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The spirit karma domain meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    template <>
+    struct grammar<karma::domain>
+    {
+        typedef karma::main_meta_grammar type;
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NONTERMINAL_MAR_05_2007_0539PM)
+#define BOOST_SPIRIT_KARMA_NONTERMINAL_MAR_05_2007_0539PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/nonterminal/rule.hpp>
+#include <boost/spirit/home/karma/nonterminal/grammar.hpp>
+#include <boost/spirit/home/karma/nonterminal/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/detail/rule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/detail/rule.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,273 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0519PM)
+#define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0519PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/detail/atomic_count.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/function_types/is_function.hpp>
+#include <boost/assert.hpp>
+#include <boost/fusion/include/pop_front.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    template <typename OutputIterator, typename Context, typename Delimiter>
+    struct virtual_component_base
+    {
+        struct no_delimiter {};
+
+        typedef typename
+            mpl::eval_if<
+                is_same<Delimiter, unused_type>,
+                mpl::identity<no_delimiter>,
+                result_of::as_component<karma::domain, Delimiter>
+            >::type
+        delimiter_type;
+
+        virtual_component_base()
+          : use_count(0)
+        {
+        }
+
+        virtual ~virtual_component_base()
+        {
+        }
+
+        virtual bool
+        generate(OutputIterator& sink, Context& context,
+            delimiter_type const& delim) = 0;
+
+        virtual bool
+        generate(OutputIterator& sink, Context& context, unused_type) = 0;
+
+        boost::detail::atomic_count use_count;
+    };
+
+    template <typename OutputIterator, typename Context, typename Delimiter>
+    inline void
+    intrusive_ptr_add_ref(
+        virtual_component_base<OutputIterator, Context, Delimiter>* p)
+    {
+        ++p->use_count;
+    }
+
+    template <typename OutputIterator, typename Context, typename Delimiter>
+    inline void
+    intrusive_ptr_release(
+        virtual_component_base<OutputIterator, Context, Delimiter>* p)
+    {
+        if (--p->use_count == 0)
+            delete p;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Component, typename Context>
+    struct needs_single_attribute
+    :   mpl::not_<
+            typename fusion::traits::is_sequence<
+                typename traits::attribute_of<
+                    karma::domain, Component, Context>::type
+            >::type
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename MustDeref, typename Parameter>
+    struct deref_if
+    {
+        typedef typename
+            mpl::eval_if<
+                MustDeref,
+                fusion::result_of::at_c<Parameter, 1>,
+                fusion::result_of::pop_front<Parameter>
+            >::type
+        type;
+
+        template <typename Param>
+        static type
+        call(Param const& param, mpl::true_)
+        {
+            return fusion::at_c<1>(param);
+        }
+
+        template <typename Param>
+        static type
+        call(Param const& param, mpl::false_)
+        {
+            return fusion::pop_front(param);
+        }
+
+        template <typename Param>
+        static type
+        call(Param const& param)
+        {
+            return call(param, MustDeref());
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Component, typename Context>
+    struct propagate_param
+    {
+        // If first element of the context (that's the parameter type) contains
+        // one element only, then the parameter type to propagate is unused,
+        // otherwise we consider to use everything except the first element of
+        // this sequence.
+        //
+        // If the resulting sequence type is a fusion sequence containing
+        // exactly one element and the right hand side expects a singular
+        // (non-sequence) parameter we pass on the first (and only) element of
+        // this sequence, otherwise we pass the parameter sequence itself.
+        typedef typename
+            boost::add_const<
+                typename boost::remove_reference<
+                    typename fusion::result_of::at_c<Context, 0>::type
+                >::type
+            >::type
+        parameter_type;
+
+        // this evaluates to mpl::true_ if the rules parameter type is unused
+        typedef typename
+            mpl::equal_to<mpl::size<parameter_type>, mpl::long_<1> >::type
+        no_parameter;
+
+        // this evaluates to mpl::true_ if the rules parameter type contains
+        // one element and the right hand side generator expects a single
+        // (non-sequence) parameter type
+        typedef typename
+            mpl::and_<
+                mpl::equal_to<mpl::size<parameter_type>, mpl::long_<2> >,
+                needs_single_attribute<Component, Context>
+            >::type
+        must_dereference;
+
+        typedef typename
+            mpl::eval_if<
+                no_parameter,
+                mpl::identity<unused_type const>,
+                deref_if<must_dereference, parameter_type>
+            >::type
+        propagated_type;
+
+        template <typename Ctx>
+        static unused_type const
+        call(Ctx& context, mpl::true_)
+        {
+            return unused;
+        }
+
+        template <typename Ctx>
+        static propagated_type
+        call(Ctx& context, mpl::false_)
+        {
+            return deref_if<must_dereference, parameter_type>::
+                call(fusion::at_c<0>(context));
+        }
+
+        template <typename Ctx>
+        static propagated_type
+        call(Ctx& context)
+        {
+            return call(context, no_parameter());
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Component, typename Context,
+        typename Delimiter, typename Auto>
+    struct virtual_component
+      : virtual_component_base<OutputIterator, Context, Delimiter>
+    {
+        typedef
+            virtual_component_base<OutputIterator, Context, Delimiter>
+        base_type;
+        typedef typename base_type::delimiter_type delimiter_type;
+        typedef typename base_type::no_delimiter no_delimiter;
+
+        virtual_component(Component const& component)
+          : component(component)
+        {
+        }
+
+        virtual ~virtual_component()
+        {
+        }
+
+        template <typename Delimiter_>
+        bool generate_main(OutputIterator& sink, Context& context,
+            Delimiter_ const& delim, mpl::false_)
+        {
+            // If Auto is false, the component's parameter is unused.
+            typedef typename Component::director director;
+            return director::generate(component, sink, context, delim, unused);
+        }
+
+        template <typename Delimiter_>
+        bool generate_main(OutputIterator& sink, Context& context,
+            Delimiter_ const& delim, mpl::true_)
+        {
+            //  If Auto is true, we pass the rule's parameters on to the
+            //  component.
+            typedef typename Component::director director;
+            return director::generate(component, sink, context, delim,
+                detail::propagate_param<Component, Context>::call(context));
+        }
+
+        bool
+        generate_main(OutputIterator& /*sink*/, Context& /*context*/, no_delimiter,
+            mpl::false_)
+        {
+            BOOST_ASSERT(false); // this should never be called
+            return false;
+        }
+
+        bool
+        generate_main(OutputIterator& /*sink*/, Context& /*context*/, no_delimiter,
+            mpl::true_)
+        {
+            BOOST_ASSERT(false); // this should never be called
+            return false;
+        }
+
+        virtual bool
+        generate(OutputIterator& sink, Context& context,
+            delimiter_type const& delim)
+        {
+            return generate_main(sink, context, delim, Auto());
+        }
+
+        virtual bool
+        generate(OutputIterator& sink, Context& context, unused_type)
+        {
+            return generate_main(sink, context, unused, Auto());
+        }
+
+        Component component;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,136 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_GRAMMAR_MAR_05_2007_0542PM)
+#define BOOST_SPIRIT_KARMA_GRAMMAR_MAR_05_2007_0542PM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/nonterminal/rule.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal_director.hpp>
+#include <boost/function_types/is_function.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename Definition>
+    struct grammar
+      : nonterminal<
+            grammar<Definition>, 
+            typename Definition::sig_type,
+            typename Definition::locals_type
+        >
+    {
+        typedef typename Definition::sig_type sig_type;
+        typedef typename Definition::locals_type locals_type;
+        typedef typename Definition::delimiter_type delimiter_type;
+        typedef typename Definition::start_type start_type;
+        typedef typename Definition::iterator_type iterator_type;
+
+        explicit grammar(Definition const& definition_)
+          : definition(definition_), start(definition_.start)
+        {
+        }
+
+        template <typename Definition_, typename Start>
+        grammar(Definition_ const& definition_, Start const& start_)
+          : definition(definition_), start(start_)
+        {
+        }
+
+    private:
+        template <typename OutputIterator, typename Context, typename Delimiter>
+        bool generate(OutputIterator& sink, Context& context, 
+            Delimiter const& delim) const
+        {
+            return start.generate(sink, context, delim);
+        }
+
+        std::string what() const
+        {
+            if (definition.name().empty())
+            {
+                return start.what();
+            }
+            else
+            {
+                return definition.name();
+            }
+        }
+
+        friend struct nonterminal_director;
+        Definition const& definition;
+        start_type const& start;
+    };
+
+    template <typename OutputIterator, typename T0 = unused_type,
+        typename T1 = unused_type, typename T2 = unused_type>
+    struct grammar_def : noncopyable
+    {
+        typedef karma::rule<OutputIterator, T0, T1, T2> start_type;
+        typedef typename start_type::iterator_type iterator_type;
+        typedef typename start_type::sig_type sig_type;
+        typedef typename start_type::locals_type locals_type;
+        typedef typename start_type::delimiter_type delimiter_type;
+
+        grammar_def(std::string const& name_ = std::string())
+          : name_(name_) {}
+
+        std::string name() const
+        {
+            return name_;
+        }
+
+        void name(std::string const& name__)
+        {
+            name_ = name__;
+        }
+
+        std::string name_;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Generator functions helping to construct a proper grammar object 
+    //  instance
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    inline grammar<Definition> 
+    make_generator(Definition const& def)
+    {
+        return grammar<Definition>(def);
+    }
+    
+    template <typename Definition, typename Start>
+    inline grammar<Definition> 
+    make_generator(Definition const& def, Start const& start)
+    {
+        return grammar<Definition>(def, start);
+    }
+    
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // forward declaration only (the default specialization is defined in the 
+    // file generate.hpp)
+    template <typename Generator, typename Delimiter>
+    struct delimiter_is_compatible;
+    
+    // If the parser is a grammar, then the delimiter must be convertible to
+    // the delimiter used with this grammar. 
+    template <typename Definition, typename Delimiter>
+    struct delimiter_is_compatible<karma::grammar<Definition>, Delimiter>
+      : is_convertible<
+            Delimiter, typename karma::grammar<Definition>::delimiter_type
+        >
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,72 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_MAR_05_2007_0436PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_MAR_05_2007_0436PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct nonterminal_director;
+    
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // nonterminal meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct nonterminal_meta_grammar
+      : meta_grammar::terminal_rule<
+            karma::domain,
+            nonterminal_holder<proto::_, proto::_>,
+            nonterminal_director
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, nonterminal_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, nonterminal_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<nonterminal_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/nonterminal.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,164 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NONTERMINAL_MAR_06_2007_0750AM)
+#define BOOST_SPIRIT_KARMA_NONTERMINAL_MAR_06_2007_0750AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/home/support/argument.hpp>
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/is_function.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/joint_view.hpp>
+#include <boost/fusion/include/single_view.hpp>
+
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/preprocessor/enum_params.hpp>
+#include <boost/preprocessor/enum_params_with_a_default.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Derived, typename Sig, typename Locals>
+    struct nonterminal
+      : proto::extends<
+            typename make_nonterminal_holder<
+                Derived const*, Derived
+            >::type,
+            Derived
+        >
+    {
+        typedef Sig sig_type;
+        typedef typename 
+            function_types::result_type<sig_type>::type 
+        result_type_;
+
+        // This is the nonterminal return type
+        typedef typename
+            mpl::if_<
+                is_same<result_type_, void>, unused_type, result_type_
+            >::type
+        result_type;
+
+        // param_types is a sequence of types passed as parameters to the 
+        // nonterminal
+        typedef typename 
+            function_types::parameter_types<sig_type>::type 
+        param_types_;
+
+        // if no parameters have been specified, we generate a single 
+        // unused_type parameter, which is needed to allow grammar parameter
+        // propagation to function correctly 
+        typedef typename
+            mpl::if_<
+                is_same<typename mpl::size<param_types_>::type, mpl::long_<0> >,
+                fusion::single_view<unused_type>, 
+                param_types_
+            >::type
+        param_types;
+
+        // locals_type is a sequence of types to be used as local variables
+        typedef typename 
+            fusion::result_of::as_vector<Locals>::type 
+        locals_type;
+
+        //  The overall context_type consist of a tuple with:
+        //      1) a tuple of the return value and parameters
+        //      2) the locals
+        typedef fusion::vector<
+                typename fusion::result_of::as_vector<
+                    fusion::joint_view<
+                        fusion::single_view<result_type const>,
+                        param_types
+                    >
+                >::type,
+                typename fusion::result_of::as_vector<locals_type>::type
+            >
+        context_type;
+
+        typedef nonterminal<Derived, Sig, Locals> self_type;
+        typedef nonterminal_holder<Derived const*, Derived> nonterminal_holder_;
+        typedef typename proto::terminal<nonterminal_holder_>::type nonterminal_tag;
+        typedef proto::extends<nonterminal_tag, Derived> base_type;
+
+        explicit nonterminal()
+          : base_type(make_tag())
+        {
+        }
+
+        // bring in the operator() overloads
+        #include <boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp>
+
+    private:
+
+        nonterminal_tag make_tag() const
+        {
+            nonterminal_tag xpr = {{static_cast<Derived const*>(this)}};
+            return xpr;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Derived, typename T0, typename T1, typename T2>
+    struct make_nonterminal
+    {
+        typedef mpl::vector<T0, T1, T2> types;
+        typedef function_types::is_function<mpl::_> is_function;
+        typedef spirit::detail::is_locals<mpl::_> is_locals;
+        typedef spirit::traits::is_component<karma::domain, mpl::_> is_delimiter;
+
+        typedef typename mpl::find_if<types, is_function>::type sig_;
+        typedef typename mpl::find_if<types, is_locals>::type locals_;
+        typedef typename mpl::find_if<types, is_delimiter>::type delimiter_;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<sig_, typename mpl::end<types>::type>,
+                mpl::identity<unused_type()>,
+                mpl::deref<sig_>
+            >::type
+        sig_type;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<locals_, typename mpl::end<types>::type>,
+                mpl::identity<locals<> >,
+                mpl::deref<locals_>
+            >::type
+        locals_type;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<delimiter_, typename mpl::end<types>::type>,
+                mpl::identity<unused_type>,
+                mpl::deref<delimiter_>
+            >::type
+        delimiter_type;
+
+        typedef nonterminal<Derived, sig_type, locals_type> type;
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,166 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NONTERMINAL_DIRECTOR_MAR_05_2007_0524PM)
+#define BOOST_SPIRIT_KARMA_NONTERMINAL_DIRECTOR_MAR_05_2007_0524PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/support/nonterminal/detail/expand_arg.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/join.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct nonterminal_director
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef typename result_of::subject<Component>::type nonterminal_holder;
+            typedef typename nonterminal_holder::nonterminal_type::param_types type;
+        };
+
+        template <
+            typename NonterminalContext, typename Nonterminal,
+            typename OutputIterator, typename Context,
+            typename Delimiter, typename Parameter>
+        static bool generate_nonterminal(
+            nonterminal_object<Nonterminal> const& x,
+            OutputIterator& sink, Context& context_,
+            Delimiter const& delim, Parameter const& param)
+        {
+            // the nonterminal_holder holds an actual nonterminal_object
+            typedef typename Nonterminal::locals_type locals_type;
+            NonterminalContext context(param, locals_type());
+            return x.obj.generate(sink, context, delim);
+        }
+
+        template <
+            typename NonterminalContext, typename Nonterminal,
+            typename OutputIterator, typename Context,
+            typename Delimiter, typename Parameter>
+        static bool generate_nonterminal(
+            Nonterminal const* ptr,
+            OutputIterator& sink, Context& /*context_*/,
+            Delimiter const& delim, Parameter const& param)
+        {
+            // the nonterminal_holder holds a pointer to a nonterminal
+            typedef typename Nonterminal::locals_type locals_type;
+            NonterminalContext context(param, locals_type());
+            return ptr->generate(sink, context, delim);
+        }
+
+        template <
+            typename NonterminalContext, typename Nonterminal,
+            typename FSequence, typename OutputIterator,
+            typename Context, typename Delimiter,
+            typename Parameter>
+        static bool generate_nonterminal(
+            parameterized_nonterminal<Nonterminal, FSequence> const& x,
+            OutputIterator& sink, Context& context_,
+            Delimiter const& delim, Parameter const& /*param*/)
+        {
+            // the nonterminal_holder holds a parameterized_nonterminal
+            typedef typename Nonterminal::locals_type locals_type;
+            fusion::single_view<unused_type const> front(unused);
+            NonterminalContext context(
+                fusion::join(
+                    front,
+                    fusion::transform(
+                        x.fseq,
+                        spirit::detail::expand_arg<Context>(context_)
+                    )
+                ),
+                locals_type()
+            );
+            return x.ptr->generate(sink, context, delim);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        // main entry point
+        ///////////////////////////////////////////////////////////////////////
+        template <
+            typename Component,
+            typename OutputIterator, typename Context,
+            typename Delimiter, typename Parameter>
+        static bool generate(
+            Component const& component, OutputIterator& sink,
+            Context& context, Delimiter const& delim, Parameter const& param)
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            nonterminal_holder;
+            
+            //  The overall context_type consists of a tuple with:
+            //      1) a tuple of the return value and parameters
+            //      2) the locals
+            //  if no signature is specified the first tuple contains
+            //  an unused_type element at position zero only.
+
+            typedef typename 
+                nonterminal_holder::nonterminal_type::context_type 
+            context_type;
+
+            typedef typename
+                mpl::if_<
+                    is_same<typename remove_const<Parameter>::type, unused_type>,
+                    context_type,
+                    Parameter
+                >::type
+            parameter_type;
+
+            // create an parameter if one is not supplied
+            parameter_type p (spirit::detail::make_value<parameter_type>::call(param));
+
+            return generate_nonterminal<context_type>(
+                subject(component).held, sink, context, delim, p
+            );
+        }
+
+        template <typename Nonterminal>
+        static std::string what_nonterminal(nonterminal_object<Nonterminal> const& x)
+        {
+            // the nonterminal_holder holds an actual nonterminal_object
+            return x.obj.what();
+        }
+
+        template <typename Nonterminal>
+        static std::string what_nonterminal(Nonterminal const* ptr)
+        {
+            // the nonterminal_holder holds a pointer to a nonterminal
+            return ptr->what();
+        }
+
+        template <typename Nonterminal, typename FSequence>
+        static std::string what_nonterminal(
+            parameterized_nonterminal<Nonterminal, FSequence> const& x)
+        {
+            // the nonterminal_holder holds a parameterized_nonterminal
+            return x.ptr->what();
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return what_nonterminal(subject(component).held);
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/rule.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,220 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM)
+#define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/karma/nonterminal/detail/rule.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/assert.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#endif
+
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename Definition>
+    struct grammar; // forward declaration
+
+    template <typename OutputIterator, typename T0 = unused_type,
+        typename T1 = unused_type, typename T2 = unused_type>
+    struct rule
+      : make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>::type
+    {
+        typedef
+            make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>
+        make_nonterminal_;
+
+        typedef typename make_nonterminal_::delimiter_type delimiter_type;
+        typedef typename make_nonterminal_::type base_type;
+        typedef detail::output_iterator<OutputIterator> iterator_type;
+        typedef rule<OutputIterator, T0, T1, T2> self_type;
+
+        typedef
+            detail::virtual_component_base<
+                iterator_type,
+                typename base_type::context_type,
+                delimiter_type
+            >
+        virtual_component;
+
+        typedef intrusive_ptr<virtual_component> pointer_type;
+
+        rule() {}
+        ~rule() {}
+
+        rule(rule const& rhs)
+          : ptr(rhs.ptr)
+        {
+        }
+
+        rule& operator=(rule const& rhs)
+        {
+            ptr = rhs.ptr;
+            return *this;
+        }
+
+        template <typename Expr>
+        rule& operator=(Expr const& xpr)
+        {
+            typedef
+                spirit::traits::is_component<karma::domain, Expr>
+            is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_generator, ());
+
+            define(xpr, mpl::false_());
+            return *this;
+        }
+
+        template <typename Expr>
+        friend rule& operator%=(rule& r, Expr const& xpr)
+        {
+            typedef
+                spirit::traits::is_component<karma::domain, Expr>
+            is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_generator, ());
+
+            r.define(xpr, mpl::true_());
+            return r;
+        }
+
+        self_type alias() const
+        {
+            self_type result;
+            result.define(*this, mpl::false_());
+            return result;
+        }
+
+        typename
+            make_nonterminal_holder<
+                nonterminal_object<self_type>
+              , self_type
+            >::type
+        copy() const
+        {
+            typename
+                make_nonterminal_holder<
+                    nonterminal_object<self_type>
+                  , self_type
+                >::type
+            result = {{*this}};
+            return result;
+        }
+
+        std::string name() const
+        {
+            return name_;
+        }
+
+        void name(std::string const& str)
+        {
+            name_ = str;
+        }
+
+    private:
+
+        template <typename Definition>
+        friend struct grammar;
+
+        template <typename Expr, typename Auto>
+        void define(Expr const& xpr, Auto)
+        {
+            typedef typename
+                result_of::as_component<karma::domain, Expr>::type
+            component;
+            typedef
+                detail::virtual_component<
+                    iterator_type,
+                    component,
+                    typename base_type::context_type,
+                    delimiter_type,
+                    Auto
+                >
+            virtual_component;
+            ptr = new virtual_component(spirit::as_component(karma::domain(), xpr));
+        }
+
+        template <typename OutputIterator_, typename Context, typename Delimiter>
+        bool generate(
+            OutputIterator_& sink, Context& context, Delimiter const& delim) const
+        {
+            return ptr->generate(sink, context, delim);
+        }
+
+        std::string what() const
+        {
+            if (name_.empty())
+            {
+                if (ptr)
+                {
+                    return "unnamed-rule";
+                }
+                else
+                {
+                    return "empty-rule";
+                }
+            }
+            else
+            {
+                return name_;
+            }
+        }
+
+        friend struct nonterminal_director;
+        pointer_type ptr;
+        std::string name_;
+    };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // forward declaration only (the default specialization is defined in the 
+    // file generate.hpp)
+    template <typename Generator, typename Delimiter>
+    struct delimiter_is_compatible;
+    
+    // If the parser is a rule, then the delimiter must be convertible to
+    // the delimiter used with this rule. 
+    template <
+        typename OutputIterator, typename T0, typename T1, typename T2, 
+        typename Delimiter
+    >
+    struct delimiter_is_compatible<
+            karma::rule<OutputIterator, T0, T1, T2>, Delimiter>
+      : is_convertible<
+            Delimiter, 
+            typename karma::rule<OutputIterator, T0, T1, T2>::delimiter_type
+        >
+    {
+    };
+
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/karma/numeric.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,19 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NUMERIC_FEB_23_2007_0507PM)
+#define BOOST_SPIRIT_KARMA_NUMERIC_FEB_23_2007_0507PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/numeric/numeric_fwd.hpp>
+#include <boost/spirit/home/karma/numeric/int.hpp>
+#include <boost/spirit/home/karma/numeric/uint.hpp>
+#include <boost/spirit/home/karma/numeric/real.hpp>
+#include <boost/spirit/home/karma/numeric/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,625 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NUMERIC_UTILS_FEB_23_2007_0841PM)
+#define BOOST_SPIRIT_KARMA_NUMERIC_UTILS_FEB_23_2007_0841PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <cmath>
+#include <limits>
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/karma/detail/string_generate.hpp>
+#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
+#include <boost/spirit/home/support/detail/math/signbit.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The value BOOST_KARMA_NUMERICS_LOOP_UNROLL specifies, how to unroll the 
+//  integer string generation loop (see below).
+//
+//      Set the value to some integer in between 0 (no unrolling) and the 
+//      largest expected generated integer string length (complete unrolling). 
+//      If not specified, this value defaults to 6.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_KARMA_NUMERICS_LOOP_UNROLL)
+#define BOOST_KARMA_NUMERICS_LOOP_UNROLL 6
+#endif
+
+#if BOOST_KARMA_NUMERICS_LOOP_UNROLL < 0 
+#error "Please set the BOOST_KARMA_NUMERICS_LOOP_UNROLL to a positive value!"
+#endif
+
+namespace boost { namespace spirit { namespace karma { 
+
+    namespace detail 
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //
+        //  return the absolute value from a given number, avoiding over- and 
+        //  underflow
+        //
+        ///////////////////////////////////////////////////////////////////////
+        inline unsigned short absolute_value (short n)
+        {
+            return (n >= 0) ? n : (unsigned short)(-n);
+        }
+        
+        inline unsigned int absolute_value (int n)
+        {
+            return (n >= 0) ? n : (unsigned int)(-n);
+        }
+
+        inline unsigned long absolute_value (long n)
+        {
+            return (n >= 0) ? n : (unsigned long)(-n);
+        }
+
+#ifdef BOOST_HAS_LONG_LONG
+        inline boost::ulong_long_type absolute_value (boost::long_long_type n)
+        {
+            return (n >= 0) ? n : (boost::ulong_long_type)(-n);
+        }
+#endif
+        
+        inline float absolute_value (float n)
+        {
+            return boost::math::signbit(n) ? boost::math::changesign(n) : n;
+        }
+        
+        inline double absolute_value (double n)
+        {
+            return boost::math::signbit(n) ? boost::math::changesign(n) : n;
+        }
+        
+        inline long double absolute_value (long double n)
+        {
+            return boost::math::signbit(n) ? boost::math::changesign(n) : n;
+        }
+        
+        template <typename T>
+        inline T absolute_value (T n)
+        {
+            using namespace std;
+            return fabs(n);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        inline bool is_negative(float n) 
+        { 
+            return boost::math::signbit(n); 
+        }
+        
+        inline bool is_negative(double n) 
+        { 
+            return boost::math::signbit(n); 
+        }
+        
+        inline bool is_negative(long double n) 
+        { 
+            return boost::math::signbit(n); 
+        }
+        
+        template <typename T>
+        inline bool is_negative(T n)
+        {
+            return (n < 0) ? true : false;
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        inline bool is_zero(float n) 
+        { 
+            return boost::math::fpclassify(n) == FP_ZERO; 
+        }
+        
+        inline bool is_zero(double n) 
+        { 
+            return boost::math::fpclassify(n) == FP_ZERO; 
+        }
+        
+        inline bool is_zero(long double n) 
+        { 
+            return boost::math::fpclassify(n) == FP_ZERO; 
+        }
+        
+        template <typename T>
+        inline bool is_zero(T n)
+        {
+            return (n == 0) ? true : false;
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        struct cast_to_long
+        {
+            static long call(float n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n));
+            }
+            
+            static long call(double n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n));
+            }
+            
+            static long call(long double n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n));
+            }
+            
+            template <typename T>
+            static long call(T n, mpl::false_)
+            {
+                // allow for ADL to find the correct overload for floor and 
+                // lround
+                using namespace std;
+                return lround(floor(n));
+            }
+
+            template <typename T>
+            static long call(T n, mpl::true_)
+            {
+                return static_cast<long>(n);
+            }
+
+            template <typename T>
+            static long call(T n)
+            {
+                return call(n, mpl::bool_<is_integral<T>::value>());
+            }
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        struct round_to_long
+        {
+            static long call(float n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n + 0.5f));
+            }
+            
+            static long call(double n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n + 0.5));
+            }
+            
+            static long call(long double n, mpl::false_)
+            {
+                return static_cast<long>(std::floor(n + 0.5l));
+            }
+            
+            template <typename T>
+            static long call(T n, mpl::false_)
+            {
+                using namespace std;
+                return lround(n);
+            }
+
+            template <typename T>
+            static long call(T n, mpl::true_)
+            {
+                return static_cast<long>(n);
+            }
+
+            template <typename T>
+            static long call(T n)
+            {
+                return call(n, mpl::bool_<is_integral<T>::value>());
+            }
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //
+        //  Traits class for radix specific number conversion
+        //
+        //      Convert a digit from binary representation to character 
+        //      representation:
+        //
+        //          static int digit(unsigned n);
+        //
+        ///////////////////////////////////////////////////////////////////////
+        template<unsigned Radix, typename Tag>
+        struct radix_traits;
+
+        // Binary
+        template<typename Tag>
+        struct radix_traits<2, Tag>
+        {
+            static int digit(unsigned n)
+            {
+                return n + '0';
+            }
+        };
+
+        // Octal
+        template<typename Tag>
+        struct radix_traits<8, Tag>
+        {
+            static int digit(unsigned n)
+            {
+                return n + '0';
+            }
+        };
+
+        // Decimal 
+        template<typename Tag>
+        struct radix_traits<10, Tag>
+        {
+            static int digit(unsigned n)
+            {
+                return n + '0';
+            }
+        };
+
+        // Hexadecimal, lower case
+        template<>
+        struct radix_traits<16, unused_type>
+        {
+            static int digit(unsigned n)
+            {
+                if (n <= 9)
+                    return n + '0';
+                return n - 10 + 'a';
+            }
+        };
+
+        // Hexadecimal, upper case
+        template<typename Tag>
+        struct radix_traits<16, Tag>
+        {
+            typedef typename Tag::char_set char_set;
+            typedef typename Tag::char_class char_class_;
+
+            static int digit(unsigned n)
+            {
+                if (n <= 9)
+                    return n + '0';
+
+                using spirit::char_class::convert;
+                return convert<char_set>::to(char_class_(), n - 10 + 'a');
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        template <unsigned Radix>
+        struct divide
+        {
+            template <typename T>
+            static T call(T& n, mpl::true_)
+            {
+                return n / Radix;
+            }
+            
+            template <typename T>
+            static T call(T& n, mpl::false_)
+            {
+                // Allow ADL to find the correct overload for floor
+                using namespace std; 
+                return floor(n / Radix);
+            }
+            
+            template <typename T>
+            static T call(T& n)
+            {
+                return call(n, mpl::bool_<is_integral<T>::value>());
+            }
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        template <unsigned Radix>
+        struct remainder
+        {
+            template <typename T>
+            static long call(T n, mpl::true_)
+            {
+                // this cast is safe since we know the result is not larger 
+                // than Radix
+                return static_cast<long>(n % Radix);
+            }
+            
+            template <typename T>
+            static long call(T n, mpl::false_)
+            {
+                // Allow ADL to find the correct overload for fmod
+                using namespace std; 
+                return cast_to_long::call(fmod(n, Radix));
+            }
+            
+            template <typename T>
+            static long call(T n)
+            {
+                return call(n, mpl::bool_<is_integral<T>::value>());
+            }
+        };
+        
+    }   // namespace detail
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The int_inserter template takes care of the integer to string 
+    //  conversion. If specified, the loop is unrolled for better performance.
+    //
+    //      Set the value BOOST_KARMA_NUMERICS_LOOP_UNROLL to some integer in 
+    //      between 0 (no unrolling) and the largest expected generated integer 
+    //      string length (complete unrolling). 
+    //      If not specified, this value defaults to 6.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+#define BOOST_KARMA_NUMERICS_INNER_LOOP_PREFIX(z, x, data)                    \
+        if (!detail::is_zero(n)) {                                            \
+            int ch = radix_type::digit(remainder_type::call(n));              \
+            n = divide_type::call(n);                                         \
+    /**/
+
+#define BOOST_KARMA_NUMERICS_INNER_LOOP_SUFFIX(z, x, data)                    \
+            *sink = ch;                                                       \
+            ++sink;                                                           \
+        }                                                                     \
+    /**/
+
+    template <unsigned Radix, typename Tag = unused_type>
+    struct int_inserter
+    {
+        typedef detail::radix_traits<Radix, Tag> radix_type;
+        typedef detail::divide<Radix> divide_type;
+        typedef detail::remainder<Radix> remainder_type;
+        
+        //  Common code for integer string representations
+        template <typename OutputIterator, typename T>
+        static bool
+        call(OutputIterator& sink, T n)
+        {
+            // remainder_type::call returns n % Radix
+            int ch = radix_type::digit(remainder_type::call(n));
+            n = divide_type::call(n);
+
+            BOOST_PP_REPEAT(
+                BOOST_KARMA_NUMERICS_LOOP_UNROLL,
+                BOOST_KARMA_NUMERICS_INNER_LOOP_PREFIX, _);
+
+            if (!detail::is_zero(n)) 
+                call(sink, n);
+
+            BOOST_PP_REPEAT(
+                BOOST_KARMA_NUMERICS_LOOP_UNROLL,
+                BOOST_KARMA_NUMERICS_INNER_LOOP_SUFFIX, _);
+
+            *sink = ch;
+            ++sink;
+            return true;
+        }
+    };
+
+#undef BOOST_KARMA_NUMERICS_INNER_LOOP_PREFIX
+#undef BOOST_KARMA_NUMERICS_INNER_LOOP_SUFFIX
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The sign_inserter template generates a sign for a given numeric value.
+    //
+    //    The parameter ForceSign allows to generate a sign even for positive  
+    //    numbers.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <bool ForceSign>
+    struct sign_inserter
+    {
+        template <typename OutputIterator>
+        static bool
+        call(OutputIterator& sink, bool /*is_zero*/, bool is_negative)
+        {
+            // generate a sign for negative numbers only
+            if (is_negative) {
+                *sink = '-';
+                ++sink;
+            }
+            return true;
+        }
+    };
+    
+    template <>
+    struct sign_inserter<true>
+    {
+        template <typename OutputIterator>
+        static bool
+        call(OutputIterator& sink, bool is_zero, bool is_negative)
+        {
+            // generate a sign for all numbers except zero
+            if (!is_zero) 
+                *sink = is_negative ? '-' : '+';
+            else 
+                *sink = ' ';
+                
+            ++sink;
+            return true;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These are helper functions for the real policies allowing to generate
+    //  a single character and a string
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag = unused_type>
+    struct char_inserter
+    {
+        template <typename OutputIterator, typename Char>
+        static bool
+        call(OutputIterator& sink, Char c)
+        {
+            return detail::generate_to(sink, c, Tag());
+        }
+    };
+    
+    template <typename Tag = unused_type>
+    struct string_inserter
+    {
+        template <typename OutputIterator, typename String>
+        static bool
+        call(OutputIterator& sink, String str)
+        {
+            return detail::string_generate(sink, str, Tag());
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The real_inserter template takes care of the floating point number to 
+    //  string conversion. The RealPolicies template parameter is used to allow
+    //  customization of the formatting process
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename RealPolicies, typename Tag = unused_type>
+    struct real_inserter    
+    {
+        enum { force_sign = RealPolicies::force_sign };
+        
+        template <typename OutputIterator>
+        static bool
+        call (OutputIterator& sink, float n, RealPolicies const& p)
+        {
+            int fpclass = boost::math::fpclassify(n);
+            if (FP_NAN == fpclass)
+                return RealPolicies::template nan<force_sign, Tag>(sink, n);
+            else if (FP_INFINITE == fpclass)
+                return RealPolicies::template inf<force_sign, Tag>(sink, n);
+            return call_n(sink, n, p);
+        }
+        
+        template <typename OutputIterator>
+        static bool
+        call (OutputIterator& sink, double n, RealPolicies const& p)
+        {
+            int fpclass = boost::math::fpclassify(n);
+            if (FP_NAN == fpclass)
+                return RealPolicies::template nan<force_sign, Tag>(sink, n);
+            else if (FP_INFINITE == fpclass)
+                return RealPolicies::template inf<force_sign, Tag>(sink, n);
+            return call_n(sink, n, p);
+        }
+        
+        template <typename OutputIterator>
+        static bool
+        call (OutputIterator& sink, long double n, RealPolicies const& p)
+        {
+            int fpclass = boost::math::fpclassify(n);
+            if (FP_NAN == fpclass)
+                return RealPolicies::template nan<force_sign, Tag>(sink, n);
+            else if (FP_INFINITE == fpclass)
+                return RealPolicies::template inf<force_sign, Tag>(sink, n);
+            return call_n(sink, n, p);
+        }
+                        
+        template <typename OutputIterator, typename U>
+        static bool
+        call (OutputIterator& sink, U n, RealPolicies const& p)
+        {
+            // we have no means of testing whether the number is normalized if
+            // the type is not float, double or long double
+            return call_n(sink, T(n), p);
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  This is the workhorse behind the real generator
+        ///////////////////////////////////////////////////////////////////////
+        template <typename OutputIterator, typename T>
+        static bool
+        call_n (OutputIterator& sink, T n, RealPolicies const& p)
+        {
+        // prepare sign and get output format
+            bool sign_val = false;
+            int flags = p.floatfield(n);
+            if (detail::is_negative(n)) 
+            {
+                n = -n;
+                sign_val = true;
+            }
+            
+        // The scientific representation requires the normalization of the 
+        // value to convert.
+
+            // allow for ADL to find the correct overloads for log10 et.al.
+            using namespace std;
+            
+            T dim = 0;
+            if (0 == (p.fixed & flags) && !detail::is_zero(n))
+            {
+                dim = log10(n);
+                if (dim > 0)
+                    n /= pow(T(10.0), (int)detail::round_to_long::call(dim));
+                else if (n < 1.) 
+                    n *= pow(T(10.0), (int)detail::round_to_long::call(-dim));
+            }
+            
+        // prepare numbers (sign, integer and fraction part)
+            unsigned precision = p.precision(n);
+            T integer_part;
+            T precexp = std::pow(10.0, (int)precision);
+            T fractional_part = modf(n, &integer_part);
+            
+            fractional_part = floor(fractional_part * precexp + 0.5);
+            if (fractional_part >= precexp) 
+            {
+                fractional_part -= precexp;
+                integer_part += 1;    // handle rounding overflow
+            }
+
+        // if trailing zeros are to be omitted, normalize the precision and
+        // fractional part
+            T long_int_part = floor(integer_part);
+            T long_frac_part = floor(fractional_part);
+            if (!p.trailing_zeros)
+            {
+                if (0 != long_frac_part) {
+                    // remove the trailing zeros
+                    while (0 != precision && 
+                           0 == detail::remainder<10>::call(long_frac_part)) 
+                    {
+                        long_frac_part = detail::divide<10>::call(long_frac_part);
+                        --precision;
+                    }
+                }
+                else {
+                    // if the fractional part is zero, we don't need to output 
+                    // any additional digits
+                    precision = 0;
+                }
+            }
+            
+        // call the actual generating functions to output the different parts
+            if (sign_val && detail::is_zero(long_int_part) && 
+                detail::is_zero(long_frac_part))
+            {
+                sign_val = false;     // result is zero, no sign please
+            }
+            
+        // generate integer part
+            bool r = p.template integer_part<force_sign>(
+                sink, long_int_part, sign_val);
+
+        // generate decimal point
+            r = r && p.dot(sink, long_frac_part);
+            
+        // generate fractional part with the desired precision
+            r = r && p.fraction_part(sink, long_frac_part, precision);
+
+            if (r && 0 == (p.fixed & flags)) {
+                return p.template exponent<Tag>(sink, 
+                    detail::round_to_long::call(dim));
+            }
+            return r;
+        }
+    };
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/karma/numeric/int.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/int.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,240 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_INT_FEB_23_2007_0840PM)
+#define BOOST_SPIRIT_KARMA_INT_FEB_23_2007_0840PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <limits>
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/numeric/numeric_fwd.hpp>
+#include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization is used for int generators not having a direct 
+    //  initializer: int_, long_ etc. These generators must be used in 
+    //  conjunction with a parameter.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct int_generator<false, T, Radix, ForceSign, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        BOOST_MPL_ASSERT_MSG(std::numeric_limits<T>::is_signed,
+            signed_unsigned_mismatch, ());
+        
+        // int has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            sign_inserter<ForceSign>::call(sink, detail::is_zero(param), 
+                detail::is_negative(param));
+            bool result = int_inserter<Radix, Tag>::call(sink, 
+                detail::absolute_value(param));
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        // this int has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, int__not_usable_without_parameter, ());
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "integer";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization is used for int generators having a direct 
+    //  initializer: int_(10), long_(20) etc. 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct int_generator<true, T, Radix, ForceSign, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        BOOST_MPL_ASSERT_MSG(std::numeric_limits<T>::is_signed,
+            signed_unsigned_mismatch, ());
+        
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            T n = fusion::at_c<0>(component.elements);
+            sign_inserter<ForceSign>::call(sink, detail::is_zero(n), 
+                detail::is_negative(n));
+            bool result = int_inserter<Radix, Tag>::call(sink, 
+                detail::absolute_value(n));
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "integer";
+        }
+    };
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case int_generator generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::int_generator<false, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef karma::int_generator<false, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, fusion::nil> type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::int_generator<true, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        int_data_type;
+        typedef fusion::vector<int_data_type> vector_type;
+
+        typedef karma::int_generator<true, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // upper_case int_generator generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::int_generator<false, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef karma::int_generator<false, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, fusion::nil> type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::int_generator<true, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        int_data_type;
+        typedef fusion::vector<int_data_type> vector_type;
+
+        typedef karma::int_generator<true, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+}}}   // namespace boost::spirit::traits
+
+#endif
Added: trunk/boost/spirit/home/karma/numeric/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,452 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_23_2007_0505PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_23_2007_0505PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/numeric/numeric_fwd.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric tags
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct int_tag
+    {};
+
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct uint_tag
+    {};
+
+    template <typename T, typename RealPolicies>
+    struct real_tag 
+    {
+        RealPolicies policies;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric specs
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct int_spec
+      : proto::terminal<int_tag<T, Radix, ForceSign> >::type
+    {};
+
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct uint_spec
+      : proto::terminal<uint_tag<T, Radix, ForceSign> >::type 
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename RealPolicies>
+    struct real_spec
+      : proto::terminal<real_tag<T, RealPolicies> >::type 
+    {
+    private:
+        typedef typename 
+            proto::terminal<real_tag<T, RealPolicies> >::type
+        base_type;
+
+        base_type make_tag(RealPolicies const& p) const
+        {
+            base_type xpr = {{p}};
+            return xpr;
+        }
+
+    public:
+        real_spec(RealPolicies const& p = RealPolicies())
+          : base_type(make_tag(p))
+        {}
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename RealPolicies>
+        struct real_policy
+        {
+            template <typename Tag>
+            static RealPolicies get(Tag) { return RealPolicies(); }
+
+            template <typename T>
+            static RealPolicies const& get(real_tag<T, RealPolicies> const& p) 
+            { return p.policies; }
+        };
+    }
+    
+}}}   // namespace boost::spirit::karma
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  test if a tag is an int tag (the basic specializations are defined in
+    //  the file support/placeholders.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct is_int_tag<karma::int_tag<T, Radix, ForceSign>, karma::domain> : 
+        mpl::true_ {};
+
+    template <typename T, unsigned Radix, bool ForceSign>
+    struct is_int_tag<karma::uint_tag<T, Radix, ForceSign>, karma::domain> : 
+        mpl::true_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  test if a tag is a real tag (the basic specializations are defined in
+    //  the file support/placeholders.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename RealPolicies>
+    struct is_real_tag<karma::real_tag<T, RealPolicies>, karma::domain> : 
+        mpl::true_ {};
+
+}}  // namespace boost::spirit
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of an int tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, bool IsLiteral>
+    struct extract_int_director;
+
+    template <bool IsLiteral>
+    struct extract_int_director<tag::bin, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned, 2, false> type;
+    };
+
+    template <bool IsLiteral>
+    struct extract_int_director<tag::oct, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned, 8, false> type;
+    };
+        
+    template <bool IsLiteral>
+    struct extract_int_director<tag::hex, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned, 16, false> type;
+    };
+        
+    template <bool IsLiteral>
+    struct extract_int_director<tag::ushort, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned short, 10, false> type;
+    };
+        
+    template <bool IsLiteral>
+    struct extract_int_director<tag::ulong, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned long, 10, false> type;
+    };
+        
+    template <bool IsLiteral>
+    struct extract_int_director<tag::uint, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, unsigned int, 10, false> type;
+    };
+    
+    template <bool IsLiteral>
+    struct extract_int_director<tag::short_, IsLiteral>    
+    {
+        typedef int_generator<IsLiteral, short, 10, false> type;
+    };
+
+    template <bool IsLiteral>
+    struct extract_int_director<tag::long_, IsLiteral>    
+    {
+        typedef int_generator<IsLiteral, long, 10, false> type;
+    };
+
+    template <bool IsLiteral>
+    struct extract_int_director<tag::int_, IsLiteral>    
+    {
+        typedef int_generator<IsLiteral, int, 10, false> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <bool IsLiteral>
+    struct extract_int_director<tag::ulong_long, IsLiteral>    
+    {
+        typedef uint_generator<IsLiteral, boost::ulong_long_type, 10, false> type;
+    };
+        
+    template <bool IsLiteral>
+    struct extract_int_director<tag::long_long, IsLiteral>    
+    {
+        typedef int_generator<IsLiteral, boost::long_long_type, 10, false> type;
+    };
+#endif
+
+    template <typename T, unsigned Radix, bool ForceSign, bool IsLiteral>
+    struct extract_int_director<int_tag<T, Radix, ForceSign>, IsLiteral>
+    {
+        typedef int_generator<IsLiteral, T, Radix, ForceSign> type;
+    };
+
+    template <typename T, unsigned Radix, bool ForceSign, bool IsLiteral>
+    struct extract_int_director<uint_tag<T, Radix, ForceSign>, IsLiteral>
+    {
+        typedef uint_generator<IsLiteral, T, Radix, ForceSign> type;
+    };
+
+    template <typename T, typename Unused>
+    struct extract_int_director_lit
+      : extract_int_director<T, true> {};
+    
+    template <typename T>
+    struct extract_int_director_plain
+      : extract_int_director<T, false> {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a floating point literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_literal_real_director;
+
+    template <>
+    struct extract_literal_real_director<float>    
+    {
+        typedef 
+            real_generator<true, float, real_generator_policies<float> > 
+        type;
+    };
+
+    template <>
+    struct extract_literal_real_director<double>    
+    {
+        typedef 
+            real_generator<true, double, real_generator_policies<double> > 
+        type;
+    };
+
+    template <>
+    struct extract_literal_real_director<long double>    
+    {
+        typedef 
+            real_generator<
+                true, long double, real_generator_policies<long double> 
+            > 
+        type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a floating point tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, bool IsLiteral>
+    struct extract_real_director;
+    
+    template <bool IsLiteral>
+    struct extract_real_director<tag::float_, IsLiteral>    
+    {
+        typedef 
+            real_generator<IsLiteral, float, real_generator_policies<float> > 
+        type;
+    };
+
+    template <bool IsLiteral>
+    struct extract_real_director<tag::double_, IsLiteral>    
+    {
+        typedef 
+            real_generator<IsLiteral, double, real_generator_policies<double> > 
+        type;
+    };
+
+    template <bool IsLiteral>
+    struct extract_real_director<tag::long_double, IsLiteral>    
+    {
+        typedef 
+            real_generator<
+                IsLiteral, long double, real_generator_policies<long double> 
+            > 
+        type;
+    };
+
+    template <typename T, typename RealPolicies, bool IsLiteral>
+    struct extract_real_director<real_tag<T, RealPolicies>, IsLiteral>
+    {
+        typedef real_generator<IsLiteral, T, RealPolicies> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename Unused>
+    struct extract_real_director_lit
+      : extract_real_director<Tag, true> {};
+    
+    template <typename Tag>
+    struct extract_real_director_plain
+      : extract_real_director<Tag, false> {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of an integer literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_literal_int_director;
+
+    template <>
+    struct extract_literal_int_director<short>    
+    {
+        typedef int_generator<true, short, 10, false> type;
+    };
+
+    template <>
+    struct extract_literal_int_director<unsigned short>    
+    {
+        typedef uint_generator<true, unsigned short, 10, false> type;
+    };
+        
+    template <>
+    struct extract_literal_int_director<int>
+    {
+        typedef int_generator<true, int, 10, false> type;
+    };
+        
+    template <>
+    struct extract_literal_int_director<unsigned int>    
+    {
+        typedef uint_generator<true, unsigned int, 10, false> type;
+    };
+        
+    template <>
+    struct extract_literal_int_director<long>
+    {
+        typedef int_generator<true, long, 10, false> type;
+    };
+        
+    template <>
+    struct extract_literal_int_director<unsigned long>    
+    {
+        typedef uint_generator<true, unsigned long, 10, false> type;
+    };
+    
+#ifdef BOOST_HAS_LONG_LONG
+    template <>
+    struct extract_literal_int_director<boost::ulong_long_type>    
+    {
+        typedef int_generator<true, boost::ulong_long_type, 10, false> type;
+    };
+
+    template <>
+    struct extract_literal_int_director<boost::long_long_type>    
+    {
+        typedef uint_generator<true, boost::long_long_type, 10, false> type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric parser meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+
+    // literals: 10, 10L, 10LL
+    struct int_literal_meta_grammar
+      : meta_grammar::compose_empty<
+            proto::if_<
+                is_int_lit_tag<proto::_arg, karma::domain>()
+            >,
+            karma::domain,
+            mpl::identity<extract_literal_int_director<mpl::_> >
+        >
+    {};
+
+    // all the different integer's as int_, uint, bin, oct, dec, hex, etc.
+    // and the corresponding int_(10), uint(10), etc.
+    struct int_meta_grammar
+      : proto::or_<
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_int_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain,
+                mpl::identity<extract_int_director_plain<mpl::_> >
+            >,
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_int_tag<proto::_arg, karma::domain>()
+                    >, 
+                    int_literal_meta_grammar
+                >, 
+                karma::domain, 
+                mpl::identity<extract_int_director_lit<mpl::_, mpl::_> >
+            >
+        >
+    {};
+
+    // floating point literals: 1.0, 1.0f, 10.1e2 etc.
+    struct real_literal_meta_grammar
+      : meta_grammar::compose_empty<
+            proto::if_<
+                is_real_lit_tag<proto::_arg, karma::domain>()
+            >,
+            karma::domain,
+            mpl::identity<extract_literal_real_director<mpl::_> >
+        >
+    {};
+    
+    struct real_meta_grammar
+      : proto::or_<
+            meta_grammar::compose_single<
+                proto::if_<
+                    is_real_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain,
+                mpl::identity<extract_real_director_plain<mpl::_> >
+            >,
+            meta_grammar::compose_function1_full<
+                proto::function<
+                    proto::if_<
+                        is_real_tag<proto::_arg, karma::domain>()
+                    >, 
+                    real_literal_meta_grammar
+                >, 
+                karma::domain, 
+                mpl::identity<extract_real_director_lit<mpl::_, mpl::_> >
+            >
+        >
+    {};
+    
+    ///////////////////////////////////////////////////////////////////////////
+    struct numeric_meta_grammar
+      : proto::or_<
+            int_meta_grammar,
+            real_meta_grammar
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////  
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
+      : mpl::true_
+    {};
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
+      : mpl::identity<numeric_meta_grammar>
+    {};
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/numeric/numeric_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/numeric_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,51 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_NUMERIC_FWD_FEB_27_2007_1338PM)
+#define BOOST_SPIRIT_KARMA_NUMERIC_FWD_FEB_27_2007_1338PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template <bool IsLiteral, typename T, unsigned Radix, bool ForceSign, 
+        typename Tag = unused_type>
+    struct int_generator;
+
+    template <bool IsLiteral, typename T, unsigned Radix, bool ForceSign, 
+        typename Tag = unused_type>
+    struct uint_generator;
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T = int, unsigned Radix = 10, bool ForceSign = false>
+    struct int_spec;
+    
+    template <typename T = unsigned int, unsigned Radix = 10, 
+        bool ForceSign = false>
+    struct uint_spec;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <bool IsLiteral, typename T, typename RealPolicies,
+        typename Tag = unused_type>
+    struct real_generator;
+    
+    template <typename T>
+    struct real_generator_policies;
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T = double, 
+        typename RealPolicies = real_generator_policies<T> >
+    struct real_spec;
+    
+}}}   // namespace boost::spirit::karma
+
+#endif
+
+
Added: trunk/boost/spirit/home/karma/numeric/real.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/real.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,246 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM)
+#define BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/numeric/real_policies.hpp>
+#include <boost/spirit/home/karma/char.hpp>
+#include <boost/spirit/home/karma/numeric/int.hpp>
+#include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
+#include <cmath>
+
+namespace boost { namespace spirit { namespace karma 
+{
+    namespace detail
+    {
+        template <typename RealPolicies>
+        struct real_policy;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization is used for real generators not having a direct 
+    //  initializer: float_, double_ etc. These generators must be used in 
+    //  conjunction with a parameter.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename RealPolicies, typename Tag>
+    struct real_generator<false, T, RealPolicies, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        // double_/float_/etc. has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            RealPolicies const& p = detail::real_policy<RealPolicies>::get(
+                fusion::at_c<0>(component.elements));
+            bool result = real_inserter<T, RealPolicies, Tag>::
+                call(sink, param, p);
+
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        // this double_/float_/etc. has no parameter attached, it needs to have 
+        // been initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, real_not_usable_without_parameter, 
+                (Component, Context));
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "real number";
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization is used for real generators having a direct 
+    //  initializer: float_(10.), double_(20.) etc. 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename RealPolicies, typename Tag>
+    struct real_generator<true, T, RealPolicies, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            RealPolicies const& p = detail::real_policy<RealPolicies>::get(
+                fusion::at_c<0>(component.elements));
+            T n = fusion::at_c<1>(component.elements);
+            bool result = real_inserter<T, RealPolicies, Tag>::call(sink, n, p);
+
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "real number";
+        }
+    };
+    
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case real generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, typename RealPolicies, typename Tag>
+    struct make_modified_component<
+        Domain, karma::real_generator<false, T, RealPolicies, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        real_policy_type;
+        typedef fusion::vector<real_policy_type> vector_type;
+
+        typedef karma::real_generator<false, T, RealPolicies, key_tag> real_type;
+        typedef component<karma::domain, real_type, vector_type> type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, typename RealPolicies, typename Tag>
+    struct make_modified_component<
+        Domain, karma::real_generator<true, T, RealPolicies, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        real_policy_type;
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 1>::type
+        real_data_type;
+        typedef fusion::vector<real_policy_type, real_data_type> vector_type;
+
+        typedef karma::real_generator<true, T, RealPolicies, key_tag> real_type;
+        typedef component<karma::domain, real_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case real generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, typename RealPolicies, typename Tag>
+    struct make_modified_component<
+        Domain, karma::real_generator<false, T, RealPolicies, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        real_policy_type;
+        typedef fusion::vector<real_policy_type> vector_type;
+
+        typedef karma::real_generator<false, T, RealPolicies, key_tag> real_type;
+        typedef component<karma::domain, real_type, vector_type> type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, typename RealPolicies, typename Tag>
+    struct make_modified_component<
+        Domain, karma::real_generator<true, T, RealPolicies, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        real_policy_type;
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 1>::type
+        real_data_type;
+        typedef fusion::vector<real_policy_type, real_data_type> vector_type;
+
+        typedef karma::real_generator<true, T, RealPolicies, key_tag> real_type;
+        typedef component<karma::domain, real_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+}}}   // namespace boost::spirit::traits
+
+#endif // defined(BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM)
Added: trunk/boost/spirit/home/karma/numeric/real_policies.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/real_policies.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,282 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
+#define BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/karma/generate.hpp>
+#include <boost/spirit/home/karma/char.hpp>
+#include <boost/spirit/home/karma/numeric/int.hpp>
+#include <cmath>
+#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
+
+namespace boost { namespace spirit { namespace karma 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  real_generator_policies, if you need special handling of your floating
+    //  point numbers, just overload this policy class and use it as a template
+    //  parameter to the karma::real_spec floating point specifier:
+    //
+    //      template <typename T>
+    //      struct scientific_policy : karma::real_generator_policies<T>
+    //      {
+    //          //  we want the numbers always to be in scientific format
+    //          static int floatfield(T n) { return scientific; }
+    //      };
+    //
+    //      typedef 
+    //          karma::real_spec<double, scientific_policy<double> > 
+    //      science_type;
+    //
+    //      karma::generate(sink, science_type(), 1.0); // will output: 1.0e00
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct real_generator_policies
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  Specifies, which representation type to use during output 
+        //  generation.
+        ///////////////////////////////////////////////////////////////////////
+        enum fmtflags 
+        {
+            scientific = 0,   // Generate floating-point values in scientific 
+                              // format (with an exponent field).
+            fixed = 1         // Generate floating-point values in fixed-point 
+                              // format (with no exponent field). 
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The default behavior is to not to require generating a sign. If 
+        //  'force_sign' is specified as true, then all generated numbers will 
+        //  have a sign ('+' or '-', zeros will have a space instead of a sign)
+        ///////////////////////////////////////////////////////////////////////
+        static bool const force_sign = false;
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The 'trailing_zeros' flag instructs the floating point generator to 
+        //  emit trailing zeros up to the required precision digits.
+        ///////////////////////////////////////////////////////////////////////
+        static bool const trailing_zeros = false;
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  Decide, which representation type to use in the generated output.
+        //
+        //  By default all numbers having an absolute value of zero or in 
+        //  between 0.001 and 100000 will be generated using the fixed format, 
+        //  all others will be generated using the scientific representation.
+        //
+        //  The trailing_zeros flag can be used to force the output of trailing 
+        //  zeros in the fractional part up to the number of digits returned by 
+        //  the precision() member function. The default is not to generate 
+        //  the trailing zeros.
+        //  
+        //      n     The floating point number to output. This can be used to 
+        //            adjust the formatting flags depending on the value of 
+        //            this number.
+        ///////////////////////////////////////////////////////////////////////
+        static int 
+        floatfield(T n)
+        {
+            if (detail::is_zero(n))
+                return fixed;
+
+            T abs_n = detail::absolute_value(n);
+            return (abs_n >= 1e5 || abs_n < 1e-3) ? scientific : fixed;
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The 'fractional_precision' constant specifies the default number of 
+        //  digits to generate for the fractional part of a floating point 
+        //  number. This is used by this (default) policies implementation 
+        //  only. If you need another fractional precision you'll have to 
+        //  overload the precision function below.
+        //  
+        //  Note: The actual number of digits for a floating point number is 
+        //        determined by the precision() function below. This allows to
+        //        have different precisions depending on the value of the
+        //        floating point number.
+        ///////////////////////////////////////////////////////////////////////
+        static unsigned int const fractional_precision = 3;
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  Return the maximum number of decimal digits to generate in the 
+        //  fractional part of the output.
+        //  
+        //      n     The floating point number to output. This can be used to 
+        //            adjust the required precision depending on the value of 
+        //            this number. If the trailing zeros flag is specified the
+        //            fractional part of the output will be 'filled' with 
+        //            zeros, if appropriate
+        //
+        //  Note:     If the trailing_zeros flag is not in effect additional
+        //            comments apply. See the comment for the fraction_part()
+        //            function below.
+        ///////////////////////////////////////////////////////////////////////
+        static unsigned int
+        precision(T)
+        {
+            // generate max. 'fractional_precision' fractional digits
+            return fractional_precision;   
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        //  Generate the integer part of the number.
+        //
+        //      sink  The output iterator to use for generation
+        //      n     The absolute value of the integer part of the floating 
+        //            point number to convert (always non-negative). 
+        //      sign  The sign of the overall floating point number to convert.
+        ///////////////////////////////////////////////////////////////////////
+        template <bool ForceSign, typename OutputIterator>
+        static bool
+        integer_part (OutputIterator& sink, T n, bool sign)
+        {
+            return sign_inserter<ForceSign>::call(
+                        sink, detail::is_zero(n), sign) &&
+                   int_inserter<10>::call(sink, n);
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  Generate the decimal point.
+        //
+        //      sink  The output iterator to use for generation
+        //      n     The fractional part of the floating point number to 
+        //            convert. Note that this number is scaled such, that 
+        //            it represents the number of units which correspond
+        //            to the value returned from the precision() function 
+        //            earlier. I.e. a fractional part of 0.01234 is
+        //            represented as 1234 when the 'Precision' is 5.
+        //
+        //            This is given to allow to decide, whether a decimal point
+        //            has to be generated at all.
+        //
+        //  Note:     If the trailing_zeros flag is not in effect additional
+        //            comments apply. See the comment for the fraction_part()
+        //            function below.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename OutputIterator>
+        static bool
+        dot (OutputIterator& sink, T)
+        {
+            return char_inserter<>::call(sink, '.');  // generate the dot by default 
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  Generate the fractional part of the number.
+        //
+        //      sink  The output iterator to use for generation
+        //      n     The fractional part of the floating point number to 
+        //            convert. This number is scaled such, that it represents 
+        //            the number of units which correspond to the 'Precision'. 
+        //            I.e. a fractional part of 0.01234 is represented as 1234 
+        //            when the 'precision_' parameter is 5.
+        //
+        //  Note: If the trailing_zeros flag is not returned from the 
+        //        floatfield() function, the 'precision_' parameter will have 
+        //        been corrected from the value the precision() function 
+        //        returned earlier (defining the maximal number of fractional 
+        //        digits) in the sense, that it takes into account trailing 
+        //        zeros. I.e. a floating point number 0.0123 and a value of 5 
+        //        returned from precision() will result in:
+        //
+        //        trailing_zeros is not specified:
+        //            n           123
+        //            precision_  4
+        //
+        //        trailing_zeros is specified:
+        //            n           1230
+        //            precision_  5
+        //
+        ///////////////////////////////////////////////////////////////////////
+        template <typename OutputIterator>
+        static bool
+        fraction_part (OutputIterator& sink, T n, unsigned precision_)
+        {
+            // allow for ADL to find the correct overload for floor and log10
+            using namespace std;
+
+            // The following is equivalent to:
+            //    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;
+            bool r = true;
+            for (/**/; r && digits < precision_; digits = digits + 1)
+                r = char_inserter<>::call(sink, '0');
+            return r && int_inserter<10>::call(sink, n);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        //  Generate the exponential part of the number (this is called only 
+        //  if the floatfield() function returned the 'scientific' flag).
+        //
+        //      sink  The output iterator to use for generation
+        //      n     The (signed) exponential part of the floating point 
+        //            number to convert. 
+        //
+        //  The Tag template parameter is either of the type unused_type or
+        //  describes the character class and conversion to be applied to any 
+        //  output possibly influenced by either the lower[...] or upper[...] 
+        //  directives.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Tag, typename OutputIterator>
+        static bool
+        exponent (OutputIterator& sink, T n)
+        {
+            T abs_n = detail::absolute_value(n);
+            bool r = char_inserter<Tag>::call(sink, 'e') &&
+                     sign_inserter<false>::call(
+                          sink, detail::is_zero(n), detail::is_negative(n));
+
+            // the C99 Standard requires at least two digits in the exponent
+            if (r && abs_n < 10)
+                r = char_inserter<Tag>::call(sink, '0');
+            return r && int_inserter<10>::call(sink, abs_n);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        //  Print the textual representations for non-normal floats (NaN and 
+        //  Inf)
+        //
+        //      sink      The output iterator to use for generation
+        //      n         The (signed) floating point number to convert. 
+        //      
+        //  The Tag template parameter is either of the type unused_type or
+        //  describes the character class and conversion to be applied to any 
+        //  output possibly influenced by either the lower[...] or upper[...] 
+        //  directives.
+        //
+        //  Note: These functions get called only if fpclassify() returned 
+        //        FP_INFINITY or FP_NAN.
+        ///////////////////////////////////////////////////////////////////////
+        template <bool ForceSign, typename Tag, typename OutputIterator>
+        static bool 
+        nan (OutputIterator& sink, T n)
+        {
+            return sign_inserter<ForceSign>::call(
+                        sink, false, detail::is_negative(n)) &&
+                   string_inserter<Tag>::call(sink, "nan");
+        }
+
+        template <bool ForceSign, typename Tag, typename OutputIterator>
+        static bool 
+        inf (OutputIterator& sink, T n)
+        {
+            return sign_inserter<ForceSign>::call(
+                        sink, false, detail::is_negative(n)) &&
+                   string_inserter<Tag>::call(sink, "inf");
+        }
+    };
+    
+}}}
+
+#endif // defined(BOOST_SPIRIT_KARMA_REAL_POLICIES_MAR_02_2007_0936AM)
Added: trunk/boost/spirit/home/karma/numeric/uint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/numeric/uint.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,224 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM)
+#define BOOST_SPIRIT_KARMA_UINT_FEB_23_2007_0840PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <limits>
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/numeric/numeric_fwd.hpp>
+#include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct uint_generator<false, T, Radix, ForceSign, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        BOOST_MPL_ASSERT_MSG(!std::numeric_limits<T>::is_signed,
+            signed_unsigned_mismatch, ());
+        
+        // uint has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            bool result = int_inserter<Radix, Tag>::call(sink, param);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        // this uint has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, uint_not_usable_without_parameter, ());
+            return false;
+        }
+        
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "unsigned integer";
+        }
+    };
+
+    template <typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct uint_generator<true, T, Radix, ForceSign, Tag>
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        BOOST_MPL_ASSERT_MSG(!std::numeric_limits<T>::is_signed,
+            signed_unsigned_mismatch, ());
+        
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            T n = fusion::at_c<0>(component.elements);
+            bool result = int_inserter<Radix, Tag>::call(sink, n);
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+        
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "unsigned integer";
+        }
+    };
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case int_ generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::uint_generator<false, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef karma::uint_generator<false, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, fusion::nil> type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::uint_generator<true, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        int_data_type;
+        typedef fusion::vector<int_data_type> vector_type;
+
+        typedef karma::uint_generator<true, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // upper_case int_ generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::uint_generator<false, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef karma::uint_generator<false, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, fusion::nil> type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+      typename T, unsigned Radix, bool ForceSign, typename Tag>
+    struct make_modified_component<
+        Domain, karma::uint_generator<true, T, Radix, ForceSign, Tag>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+
+        typedef typename 
+            fusion::result_of::value_at_c<Elements, 0>::type
+        int_data_type;
+        typedef fusion::vector<int_data_type> vector_type;
+
+        typedef karma::uint_generator<true, T, Radix, ForceSign, key_tag> int_type;
+        typedef component<karma::domain, int_type, vector_type> type;
+                
+        static type
+        call(Elements const& elements)
+        {
+            return type(elements);
+        }
+    };
+
+}}}   // namespace boost::spirit::traits
+
+#endif
Added: trunk/boost/spirit/home/karma/operator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_OPERATOR_FEB_28_2007_0351PM)
+#define BOOST_SPIRIT_KARMA_OPERATOR_FEB_28_2007_0351PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/operator/sequence.hpp>
+#include <boost/spirit/home/karma/operator/alternative.hpp>
+#include <boost/spirit/home/karma/operator/kleene.hpp>
+#include <boost/spirit/home/karma/operator/plus.hpp>
+#include <boost/spirit/home/karma/operator/optional.hpp>
+#include <boost/spirit/home/karma/operator/list.hpp>
+#include <boost/spirit/home/karma/operator/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/alternative.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,90 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1117AM)
+#define SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1117AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/operator/detail/alternative.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/as_variant.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/algorithm/any.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct alternative
+    {
+        template <typename T>
+        struct transform_child : mpl::identity<T> {};
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            // Ok, now make a variant over the attribute_sequence. It's
+            // a pity that make_variant_over does not support forward MPL
+            // sequences. We use our own conversion metaprogram (as_variant).
+            typedef typename
+                as_variant<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<alternative, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef detail::alternative_generate_functor<
+                Component, OutputIterator, Context, Delimiter, Parameter>
+            functor;
+
+            functor f(component, sink, ctx, d, param);
+            return boost::apply_visitor(f, param);
+        }
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, unused_type)
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 0>::type
+            child_component_type;
+
+            typedef typename child_component_type::director director;
+            return director::generate(
+                fusion::at_c<0>(component.elements),
+                sink, ctx, d, unused);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "alternatives[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/detail/alternative.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/detail/alternative.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,118 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM)
+#define SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    template <typename Component, typename OutputIterator,
+        typename Context, typename Delimiter, typename Parameter>
+    struct alternative_generate_functor
+    {
+        typedef bool result_type; // to satisfy boost::variant visition
+
+        template <typename Attribute, typename Got>
+        struct compute_is_compatible
+        {
+            typedef typename
+                Attribute::types
+            types; // mpl sequence of types in the variant
+
+            typedef typename
+                mpl::begin<types>::type
+            begin; // iterator to the first element
+
+            typedef typename
+                mpl::end<types>::type
+            end; // iterator to the last element
+
+            typedef typename
+                mpl::find_if<
+                    types,
+                    is_same<mpl::_1, Got> // $$$ fix this
+                >::type
+            iter;
+
+            typedef typename mpl::distance<begin, iter>::type index;
+            typedef typename mpl::not_<is_same<iter, end> >::type type;
+            enum { value = type::value };
+        };
+
+        template <typename Got>
+        struct compute_is_compatible<unused_type, Got> : mpl::false_ {};
+
+        template <typename Attribute, typename Component_, typename Context_>
+        struct is_compatible :
+            compute_is_compatible<
+                typename traits::attribute_of<
+                    karma::domain, Component_, Context_>::type,
+                Attribute>
+        {
+        };
+
+        alternative_generate_functor(Component const& component_,
+            OutputIterator& sink_, Context& ctx_,
+            Delimiter const& d, Parameter const& p)
+        : component(component_), sink(sink_), ctx(ctx_), delim(d), param(p)
+        {
+        }
+
+        template <typename Attribute>
+        bool call(Attribute const& actual_attribute, mpl::true_) const
+        {
+            typedef is_compatible<Attribute, Component, Context> is_compatible;
+            typedef typename is_compatible::index index;
+            typedef typename Component::elements_type elements;
+
+            typedef typename
+                fusion::result_of::value_at<elements, index>::type
+            child_component_type;
+
+            typedef typename child_component_type::director director;
+            return director::generate(
+                fusion::at<index>(component.elements),
+                sink, ctx, delim, actual_attribute);
+        }
+
+        template <typename Attribute>
+        bool call(Attribute const&, mpl::false_) const
+        {
+            return false;
+        }
+
+        template <typename Attribute>
+        bool operator()(Attribute const& actual_attribute) const
+        {
+            typedef mpl::bool_<
+                is_compatible<Attribute, Component, Context>::value>
+            is_compatible;
+
+            return call(actual_attribute, is_compatible());
+        }
+
+        Component const& component;
+        OutputIterator& sink;
+        Context& ctx;
+        Delimiter const& delim;
+        Parameter const& param;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/detail/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/detail/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,50 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0249PM)
+#define SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0249PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    template <typename OutputIterator, typename Context, typename Delimiter>
+    struct sequence_generate
+    {
+        sequence_generate(OutputIterator& sink_, Context& context_, 
+              Delimiter const& delim_)
+          : sink(sink_), ctx(context_), delim(delim_) 
+        {
+        }
+        
+        template <typename Component, typename Parameter>
+        bool operator()(Component const& component, Parameter& p)
+        {
+            // return true if any of the generators fail
+            typedef typename Component::director director;
+            return !director::generate(component, sink, ctx, delim, p);
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if any of the generators fail
+            typedef typename Component::director director;
+            return !director::generate(component, sink, ctx, delim, unused);
+        }
+
+        OutputIterator& sink;
+        Context& ctx;
+        Delimiter const& delim;
+    };
+    
+}}}}  // namespace boost::spirit::karma::detail
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/karma-alt.zip
==============================================================================
Binary file. No diff available.
Added: trunk/boost/spirit/home/karma/operator/karma-alt/alternative.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/karma-alt/alternative.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,90 @@
+//  Copyright (c) 2001-2007 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1117AM)
+#define SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1117AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/operator/detail/alternative.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/as_variant.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/algorithm/any.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct alternative
+    {
+        template <typename T>
+        struct transform_child : mpl::identity<T> {};
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            // Ok, now make a variant over the attribute_sequence. It's
+            // a pity that make_variant_over does not support forward MPL
+            // sequences. We use our own conversion metaprogram (as_variant).
+            typedef typename
+                as_variant<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<alternative, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef detail::alternative_generate_functor<
+                Component, OutputIterator, Context, Delimiter, Parameter>
+            functor;
+
+            functor f(component, sink, ctx, d, param);
+            return boost::apply_visitor(f, param);
+        }
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, unused_type)
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 0>::type
+            child_component_type;
+
+            typedef typename child_component_type::director director;
+            return director::generate(
+                fusion::at_c<0>(component.elements),
+                sink, ctx, d, unused);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "alternatives[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,117 @@
+//  Copyright (c) 2001-2007 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM)
+#define SPIRIT_KARMA_ALTERNATIVE_MAR_01_2007_1124AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    template <typename Component, typename OutputIterator,
+        typename Context, typename Delimiter, typename Parameter>
+    struct alternative_generate_functor
+    {
+        typedef bool result_type; // to satisfy boost::variant visition
+
+        template <typename Attribute, typename Got>
+        struct compute_is_compatible
+        {
+            typedef typename
+                Attribute::types
+            types; // mpl sequence of types in the variant
+
+            typedef typename
+                mpl::begin<types>::type
+            begin; // iterator to the first element
+
+            typedef typename
+                mpl::end<types>::type
+            end; // iterator to the last element
+
+            typedef typename
+                mpl::find_if<
+                    types,
+                    is_same<mpl::_1, Got> // $$$ fix this
+                >::type
+            iter;
+
+            typedef typename mpl::distance<begin, iter>::type index;
+            typedef typename mpl::not_<is_same<iter, end> >::type type;
+            enum { value = type::value };
+        };
+
+        template <typename Got>
+        struct compute_is_compatible<unused_type, Got> : mpl::false_ {};
+
+        template <typename Attribute, typename Component_, typename Context_>
+        struct is_compatible :
+            compute_is_compatible<
+                typename traits::attribute_of<
+                    karma::domain, Component_, Context_>::type,
+                Attribute>
+        {
+        };
+
+        alternative_generate_functor(Component const& component_,
+            OutputIterator& sink_, Context& ctx_,
+            Delimiter const& d, Parameter const& p)
+        : component(component_), sink(sink_), ctx(ctx_), delim(d), param(p)
+        {
+        }
+
+        template <typename Attribute>
+        bool call(Attribute const& actual_attribute, mpl::true_) const
+        {
+            typedef is_compatible<Attribute, Component, Context> is_compatible;
+            typedef typename is_compatible::index index;
+            typedef typename Component::elements_type elements;
+
+            typedef typename
+                fusion::result_of::value_at<elements, index>::type
+            child_component_type;
+
+            typedef typename child_component_type::director director;
+            return director::generate(
+                fusion::at<index>(component.elements),
+                sink, ctx, delim, actual_attribute);
+        }
+
+        template <typename Attribute>
+        bool call(Attribute const& actual_attribute, mpl::false_) const
+        {
+            return false;
+        }
+
+        template <typename Attribute>
+        bool operator()(Attribute const& actual_attribute) const
+        {
+            typedef mpl::bool_<
+                is_compatible<Attribute, Component, Context>::value>
+            is_compatible;
+
+            return call(actual_attribute, is_compatible());
+        }
+
+        Component const& component;
+        OutputIterator& sink;
+        Context& ctx;
+        Delimiter const& delim;
+        Parameter const& param;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/kleene.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/kleene.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,92 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_KLEENE_MAR_03_2007_0337AM)
+#define BOOST_SPIRIT_KARMA_KLEENE_MAR_03_2007_0337AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+
+#include <vector>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct kleene
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<kleene, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+            typedef typename
+                container::result_of::iterator<Parameter const>::type
+            iterator_type;
+
+            iterator_type it = container::begin(param);
+            iterator_type end = container::end(param);
+
+            // kleene fails only if the embedded parser fails
+            bool result = true;
+            for (/**/; result && !container::compare(it, end);
+                 container::next(it))
+            {
+                result = director::generate(subject(component), sink, ctx, d,
+                    container::deref(it));
+            }
+            return result;
+        }
+
+        // this kleene has no parameter attached
+//         template <typename Component, typename OutputIterator,
+//             typename Context, typename Delimiter>
+//         static bool
+//         generate(Component const&, OutputIterator&, Context&, Delimiter const&,
+//             unused_type)
+//         {
+//             BOOST_MPL_ASSERT_MSG(false, kleene_not_usable_without_parameter, ());
+//             return false;
+//         }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "kleene[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/list.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,96 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_LIST_MAY_01_2007_0229PM)
+#define SPIRIT_KARMA_LIST_MAY_01_2007_0229PM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+
+#include <vector>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+    struct list
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<list, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef typename
+                spirit::result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                spirit::result_of::right<Component>::type::director
+            rdirector;
+
+            typedef typename
+                container::result_of::iterator<Parameter const>::type
+            iterator_type;
+
+            iterator_type it = container::begin(param);
+            iterator_type end = container::end(param);
+
+            bool result = !container::compare(it, end);
+            if (result && ldirector::generate(
+                  spirit::left(component), sink, ctx, d, container::deref(it)))
+            {
+                for (container::next(it); result && !container::compare(it, end);
+                     container::next(it))
+                {
+                    result =
+                        rdirector::generate(
+                            spirit::right(component), sink, ctx, d, unused) &&
+                        ldirector::generate(
+                            spirit::left(component), sink, ctx, d, container::deref(it));
+                }
+                return result;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "list[";
+
+            typedef typename
+                spirit::result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                spirit::result_of::right<Component>::type::director
+            rdirector;
+
+            result += ldirector::what(spirit::left(component));
+            result += ", ";
+            result += rdirector::what(spirit::right(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,113 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_28_2007_0346PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_28_2007_0346PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct sequence;
+    struct alternative;
+    struct kleene;
+    struct plus;
+    struct optional;
+    struct list;
+    
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // operator meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+    struct sequence_meta_grammar
+      : proto::or_<
+            meta_grammar::binary_rule_flat<
+                karma::domain, proto::tag::shift_left, sequence,
+                main_meta_grammar
+            >,
+            meta_grammar::binary_rule_flat<
+                karma::domain, proto::tag::plus, sequence,
+                main_meta_grammar
+            >
+        >
+    {
+    };
+
+    struct alternative_meta_grammar
+      : meta_grammar::binary_rule_flat<
+            karma::domain, proto::tag::bitwise_or, alternative,
+            main_meta_grammar
+        >
+    {
+    };
+
+    struct repeat_meta_grammar
+      : proto::or_<
+            meta_grammar::unary_rule<
+                karma::domain, proto::tag::dereference, kleene,
+                main_meta_grammar
+            >,
+            meta_grammar::unary_rule<
+                karma::domain, proto::tag::negate, optional,
+                main_meta_grammar
+            >,
+            meta_grammar::unary_rule<
+                karma::domain, proto::tag::posit, plus,
+                main_meta_grammar
+            >,
+            meta_grammar::binary_rule<
+                karma::domain, proto::tag::modulus, list,
+                main_meta_grammar, main_meta_grammar
+            >
+        >
+    {
+    };
+
+    struct operator_meta_grammar
+      : proto::or_<
+            sequence_meta_grammar,
+            alternative_meta_grammar,
+            repeat_meta_grammar
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
+      : mpl::identity<operator_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/optional.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/optional.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,99 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_OPTIONAL_MARCH_31_2007_0852AM)
+#define SPIRIT_KARMA_OPTIONAL_MARCH_31_2007_0852AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/optional.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    namespace detail
+    {
+        template <typename Parameter>
+        inline bool
+        optional_is_valid(boost::optional<Parameter> const& opt)
+        {
+            return opt;
+        }
+
+        inline bool
+        optional_is_valid(unused_type)
+        {
+            return true;
+        }
+
+        template <typename Parameter>
+        inline Parameter const&
+        optional_get(boost::optional<Parameter> const& opt)
+        {
+            return get(opt) ;
+        }
+
+        inline unused_type
+        optional_get(unused_type)
+        {
+            return unused;
+        }
+    }
+
+    struct optional
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef boost::optional<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<optional, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            if (detail::optional_is_valid(param))
+            {
+                director::generate(subject(component), sink, ctx, d,
+                    detail::optional_get(param));
+            }
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "optional[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/plus.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/plus.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,95 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_POSITIVE_MAR_03_2007_0945PM)
+#define BOOST_SPIRIT_KARMA_POSITIVE_MAR_03_2007_0945PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/mpl/assert.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct plus
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<plus, Component, Iterator, Context>
+        {
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+            typedef typename
+                container::result_of::iterator<Parameter const>::type
+            iterator_type;
+
+            iterator_type it = container::begin(param);
+            iterator_type end = container::end(param);
+
+            // plus fails if the parameter is empty
+            if (it == end)
+                return false;
+
+            bool result = true;
+            for (/**/; result && !container::compare(it, end);
+                 container::next(it))
+            {
+                result = director::generate(spirit::subject(component), sink,
+                    ctx, d, container::deref(it));
+            }
+            return result;
+        }
+
+        // this kleene has no parameter attached
+//         template <typename Component, typename OutputIterator,
+//             typename Context, typename Delimiter>
+//         static bool
+//         generate(Component const&, OutputIterator&, Context&, Delimiter const&,
+//             unused_type)
+//         {
+//             BOOST_MPL_ASSERT_MSG(false, plus_not_usable_without_parameter, ());
+//             return false;
+//         }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "plus[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(spirit::subject(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/operator/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,89 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0247PM)
+#define SPIRIT_KARMA_SEQUENCE_FEB_28_2007_0247PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/operator/detail/sequence.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/algorithm/any_if.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/filter_if.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/not.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    struct sequence
+    {
+        template <typename T>
+        struct transform_child : mpl::identity<T> {};
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            typedef
+                typename fusion::result_of::as_vector<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<
+                sequence, Component, Iterator, Context
+            >
+        {
+        };
+
+        template <typename Context>
+        struct attribute_not_unused
+        {
+            template <typename Component>
+            struct apply
+              : spirit::traits::is_not_unused<typename
+                  traits::attribute_of<karma::domain, Component, Context>::type>
+            {};
+        };
+
+        template <typename Component, typename OutputIterator,
+            typename Context, typename Delimiter, typename Parameter>
+        static bool
+        generate(Component const& component, OutputIterator& sink,
+            Context& ctx, Delimiter const& d, Parameter const& param)
+        {
+            detail::sequence_generate<OutputIterator, Context, Delimiter>
+                f (sink, ctx, d);
+
+            typedef attribute_not_unused<Context> predicate;
+
+            // f returns true if *any* of the generators fail
+            return !spirit::any_if(component.elements, param, f, predicate());
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "sequence[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+
+}}} // namespace boost::spirit::karma
+
+#endif
Added: trunk/boost/spirit/home/karma/stream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_1254AM)
+#define BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_1254AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/stream/format_manip.hpp>
+#include <boost/spirit/home/karma/stream/stream.hpp>
+#include <boost/spirit/home/karma/stream/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/stream/detail/format_manip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream/detail/format_manip.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,94 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM)
+#define BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_03_2007_1424PM
+
+#include <iterator>
+#include <string>
+#include <boost/spirit/home/karma/detail/ostream_iterator.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Expr, 
+        typename Parameter = unused_type, 
+        typename Delimiter = unused_type
+    >
+    struct format_manip 
+    {
+        format_manip(Expr const& xpr, Parameter const& p, Delimiter const& d) 
+          : expr(xpr), param(p), delim(d)
+        {}
+
+        Expr const& expr;
+        Parameter const& param;
+        Delimiter const& delim;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr> 
+    inline std::basic_ostream<Char, Traits> & 
+    operator<< (std::basic_ostream<Char, Traits> &os, 
+        format_manip<Expr> const& fm)
+    {
+        ostream_iterator<Char, Char, Traits> sink(os);
+        if (!karma::generate (sink, fm.expr))
+        {
+            os.setstate(std::ios_base::failbit);
+        }
+        return os;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr, typename Parameter> 
+    inline std::basic_ostream<Char, Traits> & 
+    operator<< (std::basic_ostream<Char, Traits> &os, 
+        format_manip<Expr, Parameter> const& fm)
+    {
+        ostream_iterator<Char, Char, Traits> sink(os);
+        if (!karma::generate(sink, fm.expr, fm.param))
+        {
+            os.setstate(std::ios_base::failbit);
+        }
+        return os;
+    }
+    
+    template<typename Char, typename Traits, typename Expr, typename Delimiter> 
+    inline std::basic_ostream<Char, Traits> & 
+    operator<< (std::basic_ostream<Char, Traits> &os, 
+        format_manip<Expr, unused_type, Delimiter> const& fm)
+    {
+        ostream_iterator<Char, Char, Traits> sink(os);
+        if (!karma::generate_delimited(sink, fm.expr, fm.delim))
+        {
+            os.setstate(std::ios_base::failbit);
+        }
+        return os;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template<
+        typename Char, typename Traits, 
+        typename Expr, typename Parameter, typename Delimiter
+    > 
+    inline std::basic_ostream<Char, Traits> & 
+    operator<< (
+        std::basic_ostream<Char, Traits> &os, 
+        format_manip<Expr, Parameter, Delimiter> const& fm)
+    {
+        ostream_iterator<Char, Char, Traits> sink(os);
+        if (!karma::generate_delimited(sink, fm.expr, fm.param, fm.delim))
+        {
+            os.setstate(std::ios_base::failbit);
+        }
+        return os;
+    }
+    
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/stream/detail/iterator_ostream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream/detail/iterator_ostream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boist.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_OSTREAM_MAY_27_2007_0133PM)
+#define BOOST_SPIRIT_ITERATOR_OSTREAM_MAY_27_2007_0133PM
+
+#include <boost/iostreams/stream.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename OutputIterator, typename Char>
+    struct iterator_sink
+    {
+        typedef boost::iostreams::sink_tag category;
+        typedef Char char_type;
+        
+        iterator_sink (OutputIterator& sink_)
+          : sink(sink_)
+        {}
+        
+        // Write up to n characters from the buffer s to the output sequence, 
+        // returning the number of characters written
+        std::streamsize write (Char const* s, std::streamsize n) 
+        {
+            std::streamsize bytes_written = 0;
+            while (n--) {
+                *sink = *s;
+                ++sink; ++s; ++bytes_written;
+            }
+            return bytes_written;
+        }
+        
+        OutputIterator& sink;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/stream/format_manip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream/format_manip.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,113 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_01_2007_1211PM)
+#define BOOST_SPIRIT_KARMA_FORMAT_MANIP_MAY_01_2007_1211PM
+
+#include <boost/spirit/home/karma/generate.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/karma/stream/detail/format_manip.hpp>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/enable_if.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    inline detail::format_manip<Expr> 
+    format(Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<karma::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_generator, (Expr));
+
+        return karma::detail::format_manip<Expr>(xpr, unused, unused);
+    }
+
+    template <typename Expr, typename Parameter>
+    inline detail::format_manip<Expr, Parameter> 
+    format(Expr const& xpr, Parameter const& p)
+    {
+        typedef spirit::traits::is_component<karma::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_generator, (Expr, Parameter));
+
+        return karma::detail::format_manip<Expr, Parameter>(xpr, p, unused);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Delimiter>
+    inline detail::format_manip<Expr, unused_type, Delimiter> 
+    format_delimited(Expr const& xpr, Delimiter const& d)
+    {
+        typedef
+            spirit::traits::is_component<karma::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<karma::domain, Delimiter>
+        delimiter_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_generator, (Expr, Delimiter));
+
+        BOOST_MPL_ASSERT_MSG(delimiter_is_component::value,
+            delimiter_is_not_convertible_to_a_generator, (Expr, Delimiter));
+
+        return karma::detail::format_manip<Expr, unused_type, Delimiter>(
+            xpr, unused, d);
+    }
+
+    template <typename Expr, typename Parameter, typename Delimiter>
+    inline detail::format_manip<Expr, Parameter, Delimiter> 
+    format_delimited(Expr const& xpr, Parameter const& p, Delimiter const& d)
+    {
+        typedef
+            spirit::traits::is_component<karma::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<karma::domain, Delimiter>
+        delimiter_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_generator, 
+            (Expr, Parameter, Delimiter));
+
+        BOOST_MPL_ASSERT_MSG(delimiter_is_component::value,
+            delimiter_is_not_convertible_to_a_generator, 
+            (Expr, Parameter, Delimiter));
+
+        return karma::detail::format_manip<Expr, Parameter, Delimiter>(
+            xpr, p, d);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr> 
+    inline typename 
+        enable_if<
+            spirit::traits::is_component<karma::domain, Expr>,
+            std::basic_ostream<Char, Traits> & 
+        >::type
+    operator<< (std::basic_ostream<Char, Traits> &os, Expr const& xpr)
+    {
+        karma::detail::ostream_iterator<Char, Char, Traits> sink(os);
+        if (!karma::generate (sink, xpr))
+        {
+            os.setstate(std::ios_base::failbit);
+        }
+        return os;
+    }
+    
+}}}
+
+#endif 
+
Added: trunk/boost/spirit/home/karma/stream/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,126 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_MAY_01_2007_0313PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_MAY_01_2007_0313PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    template <typename Char>
+    struct any_stream;
+    
+    template <typename Char>
+    struct stream_director;
+    
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director for a stream
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_any_stream_director;
+    
+    template <>
+    struct extract_any_stream_director<tag::stream>
+    {
+        typedef any_stream<char> type;
+    };
+
+    template <>
+    struct extract_any_stream_director<tag::wstream>
+    {
+        typedef any_stream<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_stream_director;
+    
+    template <typename T>
+    struct extract_stream_director<tag::stream, T>
+    {
+        typedef stream_director<char> type;
+    };
+
+    template <typename T>
+    struct extract_stream_director<tag::wstream, T>
+    {
+        typedef stream_director<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // utility meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct utility_meta_grammar 
+     :  proto::or_<
+            // stream, wstream
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_stream_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain,
+                mpl::identity<extract_any_stream_director<mpl::_> >
+            >,
+            // stream(T), wstream(T)
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_stream_tag<proto::_arg, karma::domain>()
+                    >,
+                    proto::_
+                >,
+                karma::domain,
+                mpl::identity<extract_stream_director<mpl::_, mpl::_> >
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, utility_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, utility_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<utility_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/stream/stream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/stream/stream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,190 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM)
+#define BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/stream/detail/format_manip.hpp>
+#include <boost/spirit/home/karma/stream/detail/iterator_ostream.hpp>
+#include <boost/spirit/home/support/detail/hold_any.hpp>
+
+#include <iosfwd>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit 
+{ 
+    // overload the streaming operators for the unused_type
+    template <typename Char, typename Traits>
+    inline std::basic_ostream<Char, Traits>& 
+    operator<< (std::basic_ostream<Char, Traits>& os, unused_type)
+    {
+        return os;
+    }
+    
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma 
+{
+    template <typename Char>
+    struct any_stream
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef spirit::hold_any type;
+        };
+
+        // any_stream has a parameter attached
+        
+        // this overload will be used in the normal case (not called from
+        // format_manip).
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            typedef 
+                karma::detail::iterator_sink<OutputIterator, Char> 
+            sink_device;
+
+            iostreams::stream<sink_device> ostr(sink);
+            ostr << param << std::flush;        // use existing operator<<()
+            
+            if (ostr.good()) {
+                karma::delimit(sink, d);        // always do post-delimiting 
+                return true;
+            }
+            return false;
+        }
+
+        // this is a special overload to detect if the output iterator has been
+        // generated by a format_manip object.
+        template <
+            typename Component, typename T, typename Traits, 
+            typename Context, typename Delimiter, typename Parameter
+        >
+        static bool 
+        generate(Component const& component, 
+            karma::detail::output_iterator<
+                karma::detail::ostream_iterator<T, Char, Traits> 
+            >& sink, Context&, Delimiter const& d, Parameter const& param) 
+        {
+            typedef karma::detail::output_iterator<
+                karma::detail::ostream_iterator<T, Char, Traits> 
+            > output_iterator;
+            typedef 
+                karma::detail::iterator_sink<output_iterator, Char> 
+            sink_device;
+
+            iostreams::stream<sink_device> ostr(sink);
+            ostr.imbue(sink.get_ostream().getloc());
+            ostr << param << std::flush;        // use existing operator<<()
+            
+            if (ostr.good()) {
+                karma::delimit(sink, d);        // always do post-delimiting 
+                return true;
+            }
+            return false;
+        }
+        
+        // this any_stream has no parameter attached, it needs to have been 
+        // initialized from a value/variable
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const&, OutputIterator&, Context&, Delimiter const&, 
+            unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, stream__not_usable_without_parameter, 
+              (Component, OutputIterator, Delimiter));
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return "any-stream";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct stream_director
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        // stream_director has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const&) 
+        {
+            typedef 
+                karma::detail::iterator_sink<OutputIterator, Char> 
+            sink_device;
+
+            // use existing operator<<()
+            iostreams::stream<sink_device> ostr(sink);
+            ostr << fusion::at_c<0>(component.elements) << std::flush;  
+            
+            if (ostr.good()) {
+                karma::delimit(sink, d);        // always do post-delimiting 
+                return true;
+            }
+            return false;
+        }
+
+        // this is a special overload to detect if the output iterator has been
+        // generated by a format_manip object.
+        template <
+            typename Component, typename T, typename Traits, 
+            typename Context, typename Delimiter, typename Parameter
+        >
+        static bool 
+        generate(Component const& component, 
+            karma::detail::output_iterator<
+                karma::detail::ostream_iterator<T, Char, Traits> 
+            >& sink, Context&, Delimiter const& d, Parameter const&) 
+        {
+            typedef karma::detail::output_iterator<
+                karma::detail::ostream_iterator<T, Char, Traits> 
+            > output_iterator;
+            typedef 
+                karma::detail::iterator_sink<output_iterator, Char> 
+            sink_device;
+
+            // use existing operator<<()
+            iostreams::stream<sink_device> ostr(sink);
+            ostr.imbue(sink.get_ostream().getloc());
+            ostr << fusion::at_c<0>(component.elements) << std::flush; 
+            
+            if (ostr.good()) {
+                karma::delimit(sink, d);        // always do post-delimiting 
+                return true;
+            }
+            return false;
+        }
+        
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return "stream";
+        }
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/string.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_STRING_FEB_23_2007_0156PM)
+#define BOOST_SPIRIT_KARMA_STRING_FEB_23_2007_0156PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/string/lit.hpp>
+#include <boost/spirit/home/karma/string/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/karma/string/lit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/string/lit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,310 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM)
+#define BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/karma/detail/string_generate.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // generate literal strings from a given parameter
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_string
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef std::basic_string<Char> type;
+        };
+
+        // lit has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            bool result = detail::string_generate(sink, param);
+            if (result)
+                karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        // this lit has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, lit_not_usable_without_parameter, ());
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "any-string";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // generate literal strings
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct literal_string
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            bool result = detail::string_generate(sink,
+                fusion::at_c<0>(component.elements));
+            
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("\"")
+                + spirit::detail::to_narrow_string(
+                    fusion::at_c<0>(component.elements))
+                + std::string("\"")
+            ;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // lazy string generation
+    ///////////////////////////////////////////////////////////////////////////
+    struct lazy_string
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& ctx, Delimiter const& d, Parameter const& /*param*/) 
+        {
+            bool result = detail::string_generate(sink,
+                fusion::at_c<0>(component.elements)(unused, ctx));
+            
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "string";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // generate literal strings from a given parameter
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char, typename Tag>
+    struct case_any_string
+    {
+        template <typename Component, typename Context, typename Unused>
+        struct attribute
+        {
+            typedef std::basic_string<Char> type;
+        };
+
+        // case_any_string has a parameter attached
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter, typename Parameter>
+        static bool 
+        generate(Component const& /*component*/, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, Parameter const& param) 
+        {
+            bool result = detail::string_generate(sink, param, Tag());
+            karma::delimit(sink, d);           // always do post-delimiting 
+            return result;
+        }
+
+        // this case_any_string has no parameter attached, it needs to have been 
+        // initialized from a direct literal
+        template <typename Component, typename OutputIterator, 
+            typename Context, typename Delimiter>
+        static bool 
+        generate(Component const& component, OutputIterator& sink, 
+            Context& /*ctx*/, Delimiter const& d, unused_type) 
+        {
+            BOOST_MPL_ASSERT_MSG(false, lit_not_usable_without_parameter, ());
+            return false;
+        }
+
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            typedef typename Tag::char_set char_set;
+            typedef typename Tag::char_class char_class_;
+            return std::string("any-") + 
+                spirit::char_class::what<char_set>::is(char_class_())
+                + "case-string";
+        }
+    };
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // lower_case and upper_case literal_string generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::literal_string<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef std::basic_string<Char> string_type;
+        typedef fusion::vector<string_type> vector_type;
+
+        typedef 
+            component<karma::domain, karma::literal_string<Char>, vector_type> 
+        type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+            
+            string_type val(fusion::at_c<0>(elements));
+            typename string_type::iterator end = val.end();
+            for (typename string_type::iterator it = val.begin(); 
+                 it != end; ++it)
+            {
+                *it = char_set::tolower(*it);
+            }
+
+            return type(vector_type(val));
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::literal_string<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef std::basic_string<Char> string_type;
+        typedef fusion::vector<string_type> vector_type;
+
+        typedef 
+            component<karma::domain, karma::literal_string<Char>, vector_type> 
+        type;
+        
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+            
+            string_type val(fusion::at_c<0>(elements));
+            typename string_type::iterator end = val.end();
+            for (typename string_type::iterator it = val.begin(); 
+                 it != end; ++it)
+            {
+                *it = char_set::toupper(*it);
+            }
+
+            return type(vector_type(val));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // lower and upper case_any_string conversions
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::any_string<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::lower_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::lower char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+        
+        typedef component<
+            karma::domain, karma::case_any_string<Char, key_tag>, fusion::nil
+        > type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+    template <typename Domain, typename Elements, typename Modifier,
+        typename Char>
+    struct make_modified_component<
+        Domain, karma::any_string<Char>, Elements, Modifier,
+        typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::upper_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename Modifier::char_set char_set;
+        typedef spirit::char_class::tag::upper char_class_;
+        typedef spirit::char_class::key<char_set, char_class_> key_tag;
+        
+        typedef component<
+            karma::domain, karma::case_any_string<Char, key_tag>, fusion::nil
+        > type;
+        
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/string/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/string/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,236 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_22_2007_0532PM)
+#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_22_2007_0532PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace karma
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_string;
+
+    template <typename Char>
+    struct literal_string;
+
+    struct lazy_string;
+
+    struct string_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_char;
+
+    template <typename Char, typename Traits, typename Alloc>
+    struct extract_char<std::basic_string<Char, Traits, Alloc> >
+    {
+        typedef Char type;
+    };
+
+    template <typename Char, int N>
+    struct extract_char<Char[N]>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    template <typename Char, int N>
+    struct extract_char<Char(&)[N]>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    template <typename Char>
+    struct extract_char<Char*>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a string literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_lit_director_lit;
+
+    template <typename T>
+    struct extract_lit_director_lit<tag::lit, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef literal_string<char_type> type;
+    };
+
+    template <typename T>
+    struct extract_lit_director_lit<tag::wlit, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef literal_string<char_type> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_lit_director_plain;
+
+    template <>
+    struct extract_lit_director_plain<tag::lit>
+    {
+        typedef any_string<char> type;
+    };
+
+    template <>
+    struct extract_lit_director_plain<tag::wlit>
+    {
+        typedef any_string<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // string generator meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+
+    // literal strings: "hello"
+    struct string_literal_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                karma::domain, char const*, literal_string<char>
+            >,
+            meta_grammar::terminal_rule<
+                karma::domain, wchar_t const*, literal_string<wchar_t>
+            >,
+            meta_grammar::terminal_rule<
+                karma::domain, char*, literal_string<char>
+            >,
+            meta_grammar::terminal_rule<
+                karma::domain, wchar_t*, literal_string<wchar_t>
+            >
+        >
+    {
+    };
+
+    // literal strings: "hello"
+    struct basic_string_literal_meta_grammar
+      : proto::or_<
+            proto::terminal<char const*>,
+            proto::terminal<wchar_t const*>
+        >
+    {
+    };
+
+    // std::string(s)
+    struct std_string_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                karma::domain,
+                std::basic_string<char, proto::_, proto::_>,
+                literal_string<char>
+            >,
+            meta_grammar::terminal_rule<
+                karma::domain,
+                std::basic_string<wchar_t, proto::_, proto::_>,
+                literal_string<wchar_t>
+            >
+        >
+    {
+    };
+
+    // std::string(s)
+    struct basic_std_string_meta_grammar
+      : proto::or_<
+            proto::terminal<std::basic_string<char, proto::_, proto::_> >,
+            proto::terminal<std::basic_string<wchar_t, proto::_, proto::_> >
+        >
+    {
+    };
+
+    namespace detail
+    {
+        // we use this test to detect if the argument to lit is a callable
+        // function or not. Only types convertible to int or function/
+        // function objects are allowed. Therefore, if T is not convertible
+        // to an int, then we have a function/function object.
+        template <typename T>
+        struct is_not_convertible_to_int
+          : mpl::not_<is_convertible<T, int> >
+        {
+        };
+    }
+
+    // this is the string literal meta grammar
+    // literal strings: lit, lit("hello")
+    struct string_meta_grammar
+      : proto::or_<
+            string_literal_meta_grammar,
+            std_string_meta_grammar,
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_lit_tag<proto::_arg, karma::domain>()
+                >,
+                karma::domain,
+                mpl::identity<extract_lit_director_plain<mpl::_> >
+            >,
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_lit_tag<proto::_arg, karma::domain>()
+                    >,
+                    proto::or_<
+                        basic_string_literal_meta_grammar,
+                        basic_std_string_meta_grammar
+                    >
+                >,
+                karma::domain,
+                mpl::identity<extract_lit_director_lit<mpl::_, mpl::_> >
+            >,
+            meta_grammar::function1_rule<
+                karma::domain, tag::lit, lazy_string,
+                proto::if_<
+                    detail::is_not_convertible_to_int<proto::_arg>()
+                >
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Karma meta-grammar.
+    //  (see karma/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr,
+        typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr,
+        typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
+      : mpl::identity<string_meta_grammar>
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/karma/what.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/what.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,36 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_WHAT_MAY_04_2007_0116PM)
+#define BOOST_SPIRIT_WHAT_MAY_04_2007_0116PM
+
+#include <boost/spirit/home/karma/meta_grammar.hpp>
+#include <boost/mpl/assert.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename Expr>
+    inline std::string what(Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<karma::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_generator, ());
+
+        typedef typename 
+            spirit::result_of::as_component<karma::domain, Expr>::type 
+        component;
+        typedef typename component::director director;
+
+        component c = spirit::as_component(karma::domain(), xpr);
+        return director::what(c);
+    }
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/lex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEXER_MARCH_22_2007_0929PM)
+#define BOOST_SPIRIT_LEXER_MARCH_22_2007_0929PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/lexer.hpp>
+#include <boost/spirit/home/lex/domain.hpp>
+#include <boost/spirit/home/lex/meta_grammar.hpp>
+#include <boost/spirit/home/lex/tokenize_and_parse.hpp>
+
+#endif
Added: trunk/boost/spirit/home/lex/domain.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/domain.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_DOMAIN_MAR_13_2007_0140PM)
+#define BOOST_SPIRIT_LEX_DOMAIN_MAR_13_2007_0140PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+namespace boost { namespace spirit { namespace lex
+{
+    struct domain 
+    {};
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,29 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEXER_MAR_22_2007_1008PM)
+#define BOOST_SPIRIT_LEXER_MAR_22_2007_1008PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/spirit/home/lex/lexer/terminal_director.hpp>
+#include <boost/spirit/home/lex/lexer/token_def.hpp>
+#include <boost/spirit/home/lex/lexer/token_set.hpp>
+#include <boost/spirit/home/lex/lexer/char_token_def.hpp>
+#include <boost/spirit/home/lex/lexer/string_token_def.hpp>
+#include <boost/spirit/home/lex/lexer/sequence.hpp>
+#include <boost/spirit/home/lex/lexer/action.hpp>
+#include <boost/spirit/home/lex/lexer/lexer.hpp>
+#include <boost/spirit/home/lex/lexer/meta_grammar.hpp>
+
+#include <boost/spirit/home/lex/qi/state/state_switcher.hpp>
+#include <boost/spirit/home/lex/qi/state/in_state.hpp>
+#include <boost/spirit/home/lex/qi/utility/plain_token.hpp>
+#include <boost/spirit/home/lex/qi/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/action.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/action.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,95 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_LEX_ACTION_NOV_18_2007_0743PM)
+#define SPIRIT_LEX_ACTION_NOV_18_2007_0743PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/set_state.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Char>
+        struct set_state_functor
+        {
+            set_state_functor (Char const* new_state_)
+              : new_state(new_state_)
+            {
+            }
+            
+            template <typename Range, typename LexerContext>
+            void operator()(Range const&, std::size_t, LexerContext& ctx, 
+                bool&) const
+            {
+                ctx.set_state_name(new_state);
+            }
+            
+            Char const* new_state;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Char>
+        set_state_functor<Char> 
+        make_set_state(Char const* new_state)
+        {
+            return set_state_functor<Char>(new_state);
+        }
+
+        template <typename Char, typename Traits, typename Alloc>
+        set_state_functor<Char> 
+        make_set_state(std::basic_string<Char, Traits, Alloc> const& new_state)
+        {
+            return set_state_functor<Char>(new_state.c_str());
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename LexerDef, typename F>
+        inline void add_action_helper(LexerDef& lexdef, std::size_t id, F act)
+        {
+            lexdef.add_action(id, act);
+        }
+        
+        template <typename LexerDef, typename String>
+        inline void add_action_helper(LexerDef& lexdef, std::size_t id, 
+            spirit::tag::set_state_tag<String> t)
+        {
+            lexdef.add_action(id, make_set_state(t.name));
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    struct action
+    {
+        template <typename Component, typename LexerDef, typename String>
+        static void 
+        collect(Component const& component, LexerDef& lexdef, 
+            String const& state)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            director;
+            
+            // first collect the token definition information for the token_def 
+            // this action is attached to
+            director::collect(spirit::left(component), lexdef, state);
+
+            // retrieve the id of the associated token_def and register the 
+            // given semantic action with the lexer instance
+            std::size_t id = director::id(spirit::left(component));
+            detail::add_action_helper(lexdef, id, spirit::right(component));
+        }
+    };
+    
+}}} // namespace boost::spirit::lex
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/char_token_def.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/char_token_def.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,40 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_CHAR_TOKEN_DEF_MAR_28_2007_0626PM)
+#define BOOST_SPIRIT_LEX_CHAR_TOKEN_DEF_MAR_28_2007_0626PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  char_token_def 
+    //      represents a single character token definition
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    struct char_token_def
+    {
+        template <typename Component, typename LexerDef, typename String>
+        static void 
+        collect(Component const& component, LexerDef& lexdef, 
+            String const& state)
+        {
+            typedef typename result_of::subject<Component>::type char_type;
+            
+            char_type c = subject(component);
+            lexdef.add_token (state.c_str(), lex::detail::escape(c), 
+                static_cast<std::size_t>(c));
+        }
+    };
+                
+}}}  // namespace boost::spirit::lex
+
+#endif 
Added: trunk/boost/spirit/home/lex/lexer/detail/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/detail/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,38 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_SEQUENCE_FEB_28_2007_0249PM)
+#define BOOST_SPIRIT_LEX_SEQUENCE_FEB_28_2007_0249PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace lex { namespace detail
+{
+    template <typename LexerDef, typename String>
+    struct sequence_collect
+    {
+        sequence_collect(LexerDef& def_, String const& state_)
+          : def(def_), state(state_)
+        {
+        }
+        
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            Component::director::collect(component, def, state);
+            return false;   // execute for all sequence elements
+        }
+
+        LexerDef& def;
+        String const& state;
+    };
+    
+}}}}  // namespace boost::spirit::lex::detail
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexer.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexer.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,367 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_MAR_13_2007_0145PM)
+#define BOOST_SPIRIT_LEX_LEXER_MAR_13_2007_0145PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/safe_bool.hpp>
+#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/spirit/home/lex/lexer/token_def.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <string>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename LexerDef>
+        struct lexer_def_
+          : public proto::extends<
+                typename make_terminal_holder<
+                    lexer_def_<LexerDef> const*, lexer_def_<LexerDef>
+                >::type,
+                lexer_def_<LexerDef>
+            >
+        {
+        private:
+            // avoid warnings about using 'this' in constructor
+            lexer_def_& this_() { return *this; }    
+
+            // initialize proto base class
+            typedef 
+                terminal_holder<lexer_def_ const*, lexer_def_> 
+            terminal_holder;
+            typedef typename proto::terminal<terminal_holder>::type tag;
+            typedef proto::extends<tag, lexer_def_> base_type;
+
+            tag make_tag() const
+            {
+                tag xpr = {{ this }};
+                return xpr;
+            }
+            
+            typedef typename LexerDef::char_type char_type;
+            typedef typename LexerDef::string_type string_type;
+
+        public:
+            // Qi interface: metafunction calculating parser return type
+            template <typename Component, typename Context, typename Iterator>
+            struct attribute
+            {
+                //  the return value of a token set contains the matched token 
+                //  id, and the corresponding pair of iterators
+                typedef typename Iterator::base_iterator_type iterator_type;
+                typedef 
+                    fusion::vector<std::size_t, iterator_range<iterator_type> > 
+                type;
+            };
+                
+        private:
+            // Qi interface: parse functionality
+            template <typename Iterator, typename Context, typename Skipper, 
+                typename Attribute>
+            bool parse(Iterator& first, Iterator const& last, 
+                Context& context, Skipper const& skipper, Attribute& attr) const
+            {
+                qi::skip(first, last, skipper);   // always do a pre-skip
+
+                if (first != last) {
+                    typedef typename 
+                        boost::detail::iterator_traits<Iterator>::value_type 
+                    token_type;
+
+                    token_type &t = *first;
+                    if (0 != t.id()) {
+                    // any of the token definitions matched
+                        qi::detail::assign_to(t, attr);
+                        ++first;
+                        return true;
+                    }
+                }
+                return false;
+            }
+            friend struct terminal_director;
+
+            static std::string what()
+            {
+                return "lexer";
+            }
+
+            // allow to use the lexer.self.add("regex1", id1)("regex2", id2);
+            // syntax
+            struct adder
+            {
+                adder(lexer_def_& def_) 
+                : def(def_)
+                {}
+
+                adder const&
+                operator()(char_type c, std::size_t token_id = 0) const
+                {
+                    if (0 == token_id)
+                        token_id = static_cast<std::size_t>(c);
+                    def.def.add_token (def.state.c_str(), lex::detail::escape(c), 
+                        token_id);
+                    return *this;
+                }
+                adder const&
+                operator()(string_type const& s, std::size_t token_id = 0) const
+                {
+                    if (0 == token_id)
+                        token_id = next_id();
+                    def.def.add_token (def.state.c_str(), s, token_id);
+                    return *this;
+                }
+                template <typename Attribute>
+                adder const&
+                operator()(token_def<Attribute, char_type>& tokdef, 
+                    std::size_t token_id = 0) const
+                {
+                    // make sure we have a token id
+                    if (0 == token_id) {
+                        if (0 == tokdef.id()) {
+                            token_id = next_id();
+                            tokdef.id(token_id);
+                        }
+                        else {
+                            token_id = tokdef.id();
+                        }
+                    }
+                    else { 
+                    // the following assertion makes sure, that the token_def
+                    // instance has not been assigned a different id earlier
+                        BOOST_ASSERT(0 == tokdef.id() || token_id == tokdef.id());
+                        tokdef.id(token_id);
+                    }
+                    
+                    def.define(tokdef);
+                    return *this;
+                }
+                template <typename TokenSet>
+                adder const&
+                operator()(token_set<TokenSet>& tokset) const
+                {
+                    def.define(tokset);
+                    return *this;
+                }
+
+                lexer_def_& def;
+            };
+            friend struct adder;
+            
+            // allow to use lexer.self.add_pattern("pattern1", "regex1")(...);
+            // syntax
+            struct pattern_adder
+            {
+                pattern_adder(lexer_def_& def_) 
+                : def(def_)
+                {}
+
+                pattern_adder const&
+                operator()(string_type const& p, string_type const& s) const
+                {
+                    def.def.add_pattern (def.state.c_str(), p, s);
+                    return *this;
+                }
+
+                lexer_def_& def;
+            };
+            friend struct pattern_adder;
+            
+        public:
+            ///////////////////////////////////////////////////////////////////
+            template <typename Expr>
+            void define(Expr const& xpr)
+            {
+                typedef typename
+                    result_of::as_component<lex::domain, Expr>::type
+                component;
+                typedef typename component::director director;
+                
+                component c = spirit::as_component(lex::domain(), xpr);
+                director::collect(c, def, state);
+            }
+
+            lexer_def_(LexerDef& def_, string_type const& state_)
+              : base_type(make_tag()), add(this_()), add_pattern(this_()),
+                def(def_), state(state_)
+            {
+            }
+
+            // allow to switch states
+            lexer_def_ operator()(char_type const* state) const
+            {
+                return lexer_def_(def, state);
+            }
+            lexer_def_ operator()(string_type const& state) const
+            {
+                return lexer_def_(def, state);
+            }
+            
+            // allow to assign a token definition expression
+            template <typename Expr>
+            lexer_def_& operator= (Expr const& xpr)
+            {
+                typedef 
+                    spirit::traits::is_component<lex::domain, Expr> 
+                is_component;
+
+                // report invalid expression error as early as possible
+                BOOST_MPL_ASSERT_MSG(
+                    is_component::value,
+                    xpr_is_not_convertible_to_a_token_definition, ());
+
+                def.clear(state.c_str());
+                define(xpr);
+                return *this;
+            }
+
+            adder add;
+            pattern_adder add_pattern;
+            
+        private:
+            LexerDef& def;
+            string_type state;
+        };
+    
+        // allow to assign a token definition expression
+        template <typename LexerDef, typename Expr>
+        inline lexer_def_<LexerDef>&
+        operator+= (lexer_def_<LexerDef>& lexdef, Expr& xpr)
+        {
+            typedef 
+                spirit::traits::is_component<lex::domain, Expr> 
+            is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_token_definition, ());
+
+            lexdef.define(xpr);
+            return lexdef;
+        }
+        
+        template <typename LexerDef, typename Expr>
+        inline lexer_def_<LexerDef>& 
+        operator+= (lexer_def_<LexerDef>& lexdef, Expr const& xpr)
+        {
+            typedef 
+                spirit::traits::is_component<lex::domain, Expr> 
+            is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_token_definition, ());
+
+            lexdef.define(xpr);
+            return lexdef;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  This represents a lexer definition (helper for token and token set 
+    //  definitions
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Lexer>
+    class lexer_def : noncopyable, public Lexer
+    {
+    private:
+        typedef lexer_def<Lexer> self_type;
+        
+        // avoid warnings about using 'this' in constructor
+        lexer_def& this_() { return *this; }    
+
+    public:        
+        typedef Lexer lexer_type;
+        typedef detail::lexer_def_<self_type> token_set;
+        typedef typename Lexer::char_type char_type;
+        typedef std::basic_string<char_type> string_type;
+        
+        lexer_def() 
+          : self(this_(), Lexer::initial_state())  
+        {
+        }
+
+        token_set self;  // allow for easy token definition
+        
+        // this is just a dummy implementation to allow to use lexer_def 
+        // directly, without having to derive a separate class
+        void def(token_set& /*self*/) {}
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This represents a lexer object
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    class lexer : public safe_bool<lexer<Definition> >
+    {
+    public:
+        // operator_bool() is needed for the safe_bool base class
+        bool operator_bool() const { return token_def; }
+
+        typedef typename Definition::lexer_type lexer_type;
+        typedef typename Definition::char_type char_type;
+        typedef typename Definition::iterator_type iterator_type;
+
+        lexer(Definition& token_def_)
+          : token_def(token_def_) 
+        {
+            // call initialization routine supplied by the target lexer
+            token_def.def(token_def.self);
+        }
+
+        // access iterator interface
+        template <typename Iterator>
+        iterator_type begin(Iterator& first, Iterator const& last) const
+            { return token_def.begin(first, last); }
+        iterator_type end() const { return token_def.end(); }
+    
+        std::size_t map_state(char_type const* state)
+            { return token_def.add_state(state); }
+        
+        Definition& get_definition() { return token_def; }
+        Definition  const& get_definition() const { return token_def; }
+        
+    private:
+        Definition& token_def;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Metafunction returning the iterator type of the lexer given the token 
+    //  definition type.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    struct lexer_iterator
+    {
+        typedef typename lexer<Definition>::iterator_type type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Generator function helping to construct a proper lexer object 
+    //  instance
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    inline lexer<Definition> 
+    make_lexer(Definition& def)
+    {
+        return lexer<Definition>(def);
+    }
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexer_actions.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexer_actions.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,47 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_ACTIONS_FEB_13_2008_1232PM)
+#define BOOST_SPIRIT_LEX_LEXER_ACTIONS_FEB_13_2008_1232PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <iosfwd>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char, typename Traits>
+    struct echo_input_functor
+    {
+        echo_input_functor (std::basic_ostream<Char, Traits>& os_)
+          : os(os_)
+        {
+        }
+        
+        template <typename Range, typename LexerContext>
+        void operator()(Range const& r, std::size_t, LexerContext&, bool&) const
+        {
+            os << r;
+        }
+        
+        std::basic_ostream<Char, Traits>& os;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char, typename Traits>
+    inline echo_input_functor<Char, Traits> 
+    echo_input(std::basic_ostream<Char, Traits>& os)
+    {
+        return echo_input_functor<Char, Traits>(os);
+    }
+    
+///////////////////////////////////////////////////////////////////////////////
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexer_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexer_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,44 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_FWD_MAR_22_2007_1137PM)
+#define BOOST_SPIRIT_LEX_LEXER_FWD_MAR_22_2007_1137PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This component represents a token definition
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Attribute = unused_type, typename Char = char>
+    class token_def;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  token_set
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename TokenSet>
+    class token_set;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This represents a lexer definition (helper for token and token set 
+    //  definitions)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Lexer>
+    class lexer_def;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This represents a lexer object
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    class lexer;
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,257 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM)
+#define BOOST_SPIRIT_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM
+
+#include <boost/spirit/home/support/detail/lexer/state_machine.hpp>
+#include <boost/spirit/home/support/detail/lexer/consts.hpp>
+#include <boost/spirit/home/support/detail/lexer/size_t.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    template<typename Iterator>
+    class basic_iterator_tokeniser
+    {
+    public:
+        typedef std::vector<std::size_t> size_t_vector;
+
+//         static std::size_t next (const std::size_t * const lookup_,
+//             std::size_t const dfa_alphabet_, const std::size_t *  const dfa_,
+//             Iterator const& start_, Iterator &start_token_,
+//             Iterator const& end_)
+//         {
+//             if (start_token_ == end_) return 0;
+// 
+//             const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
+//             Iterator curr_ = start_token_;
+//             bool end_state_ = *ptr_ != 0;
+//             std::size_t id_ = *(ptr_ + lexer::id_index);
+//             Iterator end_token_ = start_token_;
+// 
+//             while (curr_ != end_)
+//             {
+//                 std::size_t const BOL_state_ = ptr_[lexer::bol_index];
+//                 std::size_t const EOL_state_ = ptr_[lexer::eol_index];
+// 
+//                 if (BOL_state_ && (start_token_ == start_ ||
+//                     *(start_token_ - 1) == '\n'))
+//                 {
+//                     ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
+//                 }
+//                 else if (EOL_state_ && *curr_ == '\n')
+//                 {
+//                     ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+//                 }
+//                 else
+//                 {
+//                     std::size_t const state_ = ptr_[lookup_[*curr_++]];
+// 
+//                     if (state_ == 0)
+//                     {
+//                         break;
+//                     }
+// 
+//                     ptr_ = &dfa_[state_ * dfa_alphabet_];
+//                 }
+// 
+//                 if (*ptr_)
+//                 {
+//                     end_state_ = true;
+//                     id_ = *(ptr_ + lexer::id_index);
+//                     end_token_ = curr_;
+//                 }
+//             }
+// 
+//             const std::size_t EOL_state_ = ptr_[lexer::eol_index];
+// 
+//             if (EOL_state_ && curr_ == end_)
+//             {
+//                 ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+// 
+//                 if (*ptr_)
+//                 {
+//                     end_state_ = true;
+//                     id_ = *(ptr_ + lexer::id_index);
+//                     end_token_ = curr_;
+//                 }
+//             }
+// 
+//             if (end_state_) {
+//                 // return longest match
+//                 start_token_ = end_token_;
+//             }
+//             else {
+//                 id_ = lexer::npos;
+//             }
+// 
+//             return id_;
+//         }
+
+        static std::size_t next (boost::lexer::state_machine const& state_machine_,
+            std::size_t &dfa_state_, Iterator const& start_,
+            Iterator &start_token_, Iterator const& end_)
+        {
+            if (start_token_ == end_) return 0;
+
+        again:
+            std::size_t const* lookup_ = &state_machine_._lookup[dfa_state_]->
+                front ();
+            std::size_t dfa_alphabet_ = state_machine_._dfa_alphabet[dfa_state_];
+            std::size_t const* dfa_ = &state_machine_._dfa[dfa_state_]->front ();
+            std::size_t const* ptr_ = dfa_ + dfa_alphabet_;
+            Iterator curr_ = start_token_;
+            bool end_state_ = *ptr_ != 0;
+            std::size_t id_ = *(ptr_ + boost::lexer::id_index);
+            Iterator end_token_ = start_token_;
+
+            while (curr_ != end_)
+            {
+                std::size_t const BOL_state_ = ptr_[boost::lexer::bol_index];
+                std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index];
+
+                if (BOL_state_ && (start_token_ == start_ ||
+                    *(start_token_ - 1) == '\n'))
+                {
+                    ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
+                }
+                else if (EOL_state_ && *curr_ == '\n')
+                {
+                    ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+                }
+                else
+                {
+                    std::size_t const state_ = ptr_[lookup_[*curr_++]];
+
+                    if (state_ == 0)
+                    {
+                        break;
+                    }
+
+                    ptr_ = &dfa_[state_ * dfa_alphabet_];
+                }
+
+                if (*ptr_)
+                {
+                    end_state_ = true;
+                    id_ = *(ptr_ + boost::lexer::id_index);
+                    dfa_state_ = *(ptr_ + boost::lexer::state_index);
+                    end_token_ = curr_;
+                }
+            }
+
+            std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index];
+
+            if (EOL_state_ && curr_ == end_)
+            {
+                ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+
+                if (*ptr_)
+                {
+                    end_state_ = true;
+                    id_ = *(ptr_ + boost::lexer::id_index);
+                    dfa_state_ = *(ptr_ + boost::lexer::state_index);
+                    end_token_ = curr_;
+                }
+            }
+
+            if (end_state_) {
+                // return longest match
+                start_token_ = end_token_;
+
+                if (id_ == 0) 
+                    goto again;
+            }
+            else {
+                id_ = boost::lexer::npos;
+            }
+            
+            return id_;
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        static 
+        std::size_t next (boost::lexer::state_machine const& state_machine_,
+            Iterator const& start_, Iterator &start_token_, Iterator const& end_)
+        {
+            if (start_token_ == end_) return 0;
+
+            std::size_t const* lookup_ = &state_machine_._lookup[0]->front();
+            std::size_t dfa_alphabet_ = state_machine_._dfa_alphabet[0];
+            std::size_t const* dfa_ = &state_machine_._dfa[0]->front ();
+            std::size_t const* ptr_ = dfa_ + dfa_alphabet_;
+            Iterator curr_ = start_token_;
+            bool end_state_ = *ptr_ != 0;
+            std::size_t id_ = *(ptr_ + boost::lexer::id_index);
+            Iterator end_token_ = start_token_;
+
+            while (curr_ != end_)
+            {
+                std::size_t const BOL_state_ = ptr_[boost::lexer::bol_index];
+                std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index];
+
+                if (BOL_state_ && (start_token_ == start_ ||
+                    *(start_token_ - 1) == '\n'))
+                {
+                    ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
+                }
+                else if (EOL_state_ && *curr_ == '\n')
+                {
+                    ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+                }
+                else
+                {
+                    std::size_t const state_ = ptr_[lookup_[*curr_++]];
+
+                    if (state_ == 0)
+                    {
+                        break;
+                    }
+
+                    ptr_ = &dfa_[state_ * dfa_alphabet_];
+                }
+
+                if (*ptr_)
+                {
+                    end_state_ = true;
+                    id_ = *(ptr_ + boost::lexer::id_index);
+                    end_token_ = curr_;
+                }
+            }
+
+            std::size_t const EOL_state_ = ptr_[boost::lexer::eol_index];
+
+            if (EOL_state_ && curr_ == end_)
+            {
+                ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+
+                if (*ptr_)
+                {
+                    end_state_ = true;
+                    id_ = *(ptr_ + boost::lexer::id_index);
+                    end_token_ = curr_;
+                }
+            }
+
+            if (end_state_) {
+                // return longest match
+                start_token_ = end_token_;
+            }
+            else {
+                id_ = boost::lexer::npos;
+            }
+            
+            return id_;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    typedef basic_iterator_tokeniser<char const *> tokeniser;
+    typedef basic_iterator_tokeniser<wchar_t const *> wtokeniser;
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,357 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM)
+#define BOOST_SPIRIT_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+#include <boost/function.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/detail/workaround.hpp>
+#include <map>
+#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/state_machine.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp>
+
+#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+#define BOOST_SPIRIT_EOF_PREFIX static
+#else
+#define BOOST_SPIRIT_EOF_PREFIX 
+#endif
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator, typename HasActors, typename HasState>
+        struct Data;    // no default specialization
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  doesn't support no state and no actors
+        template <typename Iterator>
+        struct Data<Iterator, mpl::false_, mpl::false_>
+        {
+            typedef iterator_range<Iterator> iterpair_type;
+            typedef typename 
+                boost::detail::iterator_traits<Iterator>::value_type 
+            char_type;
+
+            typedef unused_type semantic_actions_type;
+
+            // initialize the shared data 
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : state_machine(data_.state_machine_),
+                rules(data_.rules_), 
+                first(first_), last(last_)
+            {}
+
+            std::size_t next(Iterator& end)
+            {
+                typedef basic_iterator_tokeniser<Iterator> tokenizer;
+                return tokenizer::next(state_machine, first, end, last);
+            }
+
+            // nothing to invoke, so this is empty
+            bool invoke_actions(std::size_t, Iterator const&) 
+            {
+                return true;    // always accept
+            }
+
+            std::size_t get_state() const { return 0; }
+            void set_state_name (char_type const* state) {}
+
+            boost::lexer::state_machine const& state_machine;
+            boost::lexer::basic_rules<char_type> const& rules;
+            Iterator& first;
+            Iterator last;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  doesn't support actors
+        template <typename Iterator>
+        struct Data<Iterator, mpl::false_, mpl::true_>
+          : Data<Iterator, mpl::false_, mpl::false_>
+        {
+            typedef Data<Iterator, mpl::false_, mpl::false_> base_type;
+            
+            // initialize the shared data 
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : base_type(data_, first_, last_), state(0)
+            {}
+
+            std::size_t next(Iterator& end)
+            {
+                typedef basic_iterator_tokeniser<Iterator> tokenizer;
+                return tokenizer::next(this->state_machine, state, 
+                    this->first, end, this->last);
+            }
+
+            std::size_t& get_state() { return state; }
+            void set_state_name (char_type const* new_state) 
+            { 
+                std::size_t state_id = this->rules.state(new_state);
+                
+                // if the following assertion fires you've probably been using 
+                // a lexer state name which was not defined in your token 
+                // definition
+                BOOST_ASSERT(state_id != boost::lexer::npos);
+
+                if (state_id != boost::lexer::npos)
+                    state = state_id;
+            }
+
+            std::size_t state;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  does support actors, but may have no state
+        template <typename Iterator, typename HasState>
+        struct Data<Iterator, mpl::true_, HasState> 
+          : Data<Iterator, mpl::false_, HasState>
+        {
+            typedef Data<Iterator, mpl::false_, HasState> base_type;
+            
+            typedef iterator_range<Iterator> iterpair_type;
+            typedef typename 
+                boost::detail::iterator_traits<Iterator>::value_type 
+            char_type;
+
+            typedef void functor_type(iterpair_type, std::size_t, Data&, bool&);
+            typedef boost::function<functor_type> functor_wrapper_type;
+            typedef std::multimap<std::size_t, functor_wrapper_type> 
+                semantic_actions_type;
+
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : base_type(data_, first_, last_),
+                actions(data_.actions_)
+            {}
+
+            // invoke attached semantic actions, if defined
+            bool invoke_actions(std::size_t id, Iterator const& end)
+            {
+                if (actions.empty()) 
+                    return true;  // nothing to invoke, continue with 'match'
+
+                iterpair_type itp(this->first, end);
+                bool match = true;
+                
+                typedef typename 
+                    semantic_actions_type::const_iterator 
+                iterator_type;
+                
+                std::pair<iterator_type, iterator_type> p = actions.equal_range(id);
+                while (p.first != p.second)
+                {
+                    ((*p.first).second)(itp, id, *this, match);
+                    if (!match)
+                        return false;   // return a 'no-match'
+                    ++p.first;
+                }
+                return true;    // normal execution
+            }
+            
+            semantic_actions_type const& actions;
+        };
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  lexertl_functor is a template usable as the functor object for the 
+    //  multi_pass iterator allowing to wrap a lexertl based dfa into a 
+    //  iterator based interface.
+    //  
+    //    Iterator:   the type of the underlying iterator
+    //    Token:      the type of the tokens produced by this functor
+    //                this needs to expose a constructor with the following
+    //                prototype:
+    //
+    //                Token(std::size_t id, std::size_t state, 
+    //                      Iterator start, Iterator end)
+    //
+    //                where 'id' is the token id, state is the lexer state,
+    //                this token has been matched in, and 'first' and 'end'  
+    //                mark the start and the end of the token with respect 
+    //                to the underlying character stream.
+    //    SupportsActors:
+    //                this is expected to be a mpl::bool_, if mpl::true_ the
+    //                lexertl_functor invokes functors which (optionally) have 
+    //                been attached to the token definitions.
+    //    SupportState:
+    //                this is expected to be a mpl::bool_, if mpl::true_ the
+    //                lexertl_functor supports different lexer states, 
+    //                otherwise no lexer state is supported.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, 
+        typename Iterator = typename Token::iterator_type, 
+        typename SupportsActors = mpl::false_, 
+        typename SupportsState = typename Token::has_state>
+    class lexertl_functor
+    {
+    public:
+        typedef typename 
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+
+    private:
+        // Needed by compilers not implementing the resolution to DR45. For
+        // reference, see
+        // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
+        template <typename Iterator_, typename HasActors, typename HasState> 
+        friend struct detail::Data;
+
+        // Helper template allowing to assign a value on exit
+        template <typename T>
+        struct assign_on_exit
+        {
+            assign_on_exit(T& dst_, T const& src_)
+              : dst(dst_), src(src_)
+            {}
+            ~assign_on_exit()
+            {
+                dst = src;
+            }
+            
+            T& dst;
+            T const& src;
+        };
+        
+    public:
+        lexertl_functor()
+#if 0 != __DECCXX_VER || BOOST_INTEL_CXX_VERSION > 900 || defined(__PGI)
+          , eof()
+#endif // 0 != __DECCXX_VER
+        {}
+        
+        ///////////////////////////////////////////////////////////////////////
+        // interface to the multi_pass_policies::split_functor_input policy
+        typedef Token result_type;
+        typedef lexertl_functor unique;
+        typedef detail::Data<Iterator, SupportsActors, SupportsState> shared;
+        
+        BOOST_SPIRIT_EOF_PREFIX result_type const eof;
+    
+        ///////////////////////////////////////////////////////////////////////
+        typedef Iterator iterator_type;
+        typedef typename shared::semantic_actions_type semantic_actions_type;
+
+        template <typename MultiPass>
+        static result_type& get_next(MultiPass& mp, result_type& result)
+        {
+            shared& data = mp.shared->ftor;
+            if (data.first == data.last) 
+                return result = eof;
+
+            Iterator end = data.first;
+            std::size_t id = data.next(end);
+            
+            if (boost::lexer::npos == id) {   // no match
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+                std::string next;
+                Iterator it = data.first;
+                for (std::size_t i = 0; i < 10 && it != data.last; ++it, ++i)
+                    next += *it;
+
+                std::cerr << "Not matched, in state: " << data.state 
+                          << ", lookahead: >" << next << "<" << std::endl;
+#endif
+                result = result_type(0);
+            }
+            else if (0 == id) {         // EOF reached
+                result = eof;
+            }
+            else {
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+                {
+                    std::string next;
+                    Iterator it = data.first;
+                    for (std::size_t i = 0; i < 10 && it != data.last; ++it, ++i)
+                        next += *it;
+
+                    std::cerr << "Matched: " << id << ", in state: " 
+                              << data.state << ", string: >" 
+                              << std::basic_string<char_type>(data.first, end) << "<"
+                              << ", lookahead: >" << next << "<" << std::endl;
+                }
+#endif
+                // invoke_actions might change state
+                std::size_t state = data.get_state();
+                
+                // invoke attached semantic actions, if defined
+                if (!data.invoke_actions(id, end))
+                {
+                    // one of the semantic actions signaled no-match
+                    result = result_type(0); 
+                }
+                else 
+                {
+                    // return matched token, advancing 'data.first' past the 
+                    // matched sequence
+                    assign_on_exit<Iterator> on_exit(data.first, end);
+                    result = result_type(id, state, data.first, end);
+                }
+            }
+            return result;
+        }
+
+        // set_state are propagated up to the iterator interface, allowing to 
+        // manipulate the current lexer state through any of the exposed 
+        // iterators.
+        template <typename MultiPass>
+        static std::size_t set_state(MultiPass& mp, std::size_t state_) 
+        { 
+            std::size_t oldstate = mp.shared->ftor.state;
+            mp.shared->ftor.state = state_;
+
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+            std::cerr << "Switching state from: " << oldstate 
+                      << " to: " << state_
+                      << std::endl;
+#endif
+            return oldstate; 
+        }
+        
+        template <typename MultiPass>
+        static std::size_t 
+        map_state(MultiPass const& mp, char_type const* statename)  
+        { 
+            return mp.shared->ftor.rules.state(statename);
+        }
+        
+        // we don't need this
+        template <typename MultiPass>
+        static void destroy(MultiPass const& mp)
+        {}  
+    };
+
+#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+    ///////////////////////////////////////////////////////////////////////////
+    //  eof token
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, typename Iterator, typename SupportsActors, 
+        typename SupportsState>
+    typename lexertl_functor<
+            Token, Iterator, SupportsActors, SupportsState>::result_type const
+        lexertl_functor<
+                Token, Iterator, SupportsActors, SupportsState>::eof = 
+            typename lexertl_functor<
+                Token, Iterator, SupportsActors, SupportsState>::result_type();
+#endif // 0 != __COMO_VERSION__
+
+}}}
+
+#undef BOOST_SPIRIT_EOF_PREFIX
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_generate_static.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_generate_static.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,559 @@
+//  Copyright (c) 2008 Ben Hanson
+//  Copyright (c) 2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXERTL_GENERATE_CPP_FEB_10_2008_0855PM)
+#define BOOST_SPIRIT_LEX_LEXERTL_GENERATE_CPP_FEB_10_2008_0855PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/detail/lexer/char_traits.hpp>
+#include <boost/spirit/home/support/detail/lexer/consts.hpp>
+#include <boost/spirit/home/support/detail/lexer/size_t.hpp>
+#include <boost/spirit/home/support/detail/lexer/state_machine.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace lex { namespace detail
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    // Generate a table of the names of the used lexer states, which is a bit 
+    // tricky, because the table stored with the rules is sorted based on the 
+    // names, but we need it sorted using the state ids.
+    template <typename Char>
+    inline bool 
+    generate_cpp_state_names (boost::lexer::basic_rules<Char> const& rules_,
+        std::ostream &os_, char const* name_suffix = "")
+    {
+        // we need to re-sort the state names in ascending order if the state 
+        // ids, filling possible gaps in between later
+	      typedef typename 
+	          boost::lexer::basic_rules<Char>::string_size_t_map::const_iterator
+	      state_iterator;
+	      typedef std::map<std::size_t, char const*> reverse_state_map_type;
+	      
+        reverse_state_map_type reverse_state_map;
+	      state_iterator send = rules_.statemap().end();
+	      for (state_iterator sit = rules_.statemap().begin(); sit != send; ++sit)
+	      {
+	          typedef typename reverse_state_map_type::value_type value_type;
+	          reverse_state_map.insert(value_type((*sit).second, (*sit).first.c_str()));
+	      }
+        
+	      os_ << "// this table defines the names of the lexer states\n";
+	      os_ << "char const* const lexer_state_names" << name_suffix 
+	          << "[" << rules_.statemap().size() << "] = \n{\n";
+	          
+	      typedef typename reverse_state_map_type::iterator iterator;
+	      iterator rend = reverse_state_map.end();
+	      std::size_t last_id = 0;
+	      for (iterator rit = reverse_state_map.begin(); rit != rend; ++rit)
+	      {
+	          for (/**/; last_id < (*rit).first; ++last_id)
+            {
+	              os_ << "    0,  // \"<undefined state>\"\n";
+	          }
+	          os_ << "    \"" << (*rit).second << "\",\n";
+	      }
+	      os_ << "};\n\n";
+	      
+        return true;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // Generate a tokenizer for the given state machine.
+    template <typename Char>
+    inline bool 
+    generate_cpp (boost::lexer::state_machine const& sm_, 
+        boost::lexer::basic_rules<Char> const& rules_, 
+        std::ostream &os_, char const* name_suffix = "", 
+        bool skip_on_nomatch = true, bool optimize_parameters = true)
+    {
+        if (sm_._lookup->empty())
+            return false;
+            
+	      std::size_t const dfas_ = sm_._dfa->size();
+	      std::size_t const lookups_ = sm_._lookup->front()->size();
+
+	      os_ << "// Copyright (c) 2008 Ben Hanson\n";
+	      os_ << "//\n";
+	      os_ << "// Distributed under the Boost Software License, "
+	          "Version 1.0. (See accompanying\n";
+	      os_ << "// file licence_1_0.txt or copy at "
+	          "http://www.boost.org/LICENSE_1_0.txt)\n\n";
+	      os_ << "// Auto-generated by boost::lexer\n";
+
+        std::string guard(__DATE__ "_" __TIME__);
+        std::string::size_type p = guard.find_first_of(": ");
+        while (std::string::npos != p) 
+        {
+            guard.replace(p, 1, "_");
+            p = guard.find_first_of(": ", p);
+        }
+      
+	      os_ << "#if !defined(BOOST_SPIRIT_LEXER_NEXT_TOKEN_" << guard << ")\n";
+	      os_ << "#define BOOST_SPIRIT_LEXER_NEXT_TOKEN_" << guard << "\n\n";
+    	
+	      os_ << "#include <boost/detail/iterator.hpp>\n";
+	      os_ << "#include <boost/spirit/home/support/detail/lexer/char_traits.hpp>\n\n";
+
+	      os_ << "// the generated table of state names and the tokenizer have to be\n"
+	             "// defined in the boost::spirit::lex::static namespace\n";
+	      os_ << "namespace boost { namespace spirit { namespace lex { "
+	          "namespace static_ {\n\n";
+
+        // generate the table containing state names 
+        if (!generate_cpp_state_names(rules_, os_, name_suffix))
+            return false;
+
+	      os_ << "template<typename Iterator>\n";
+	      os_ << "std::size_t next_token" << name_suffix  << " (";
+
+        if (dfas_ > 1 || !optimize_parameters)
+        {
+	          os_ << "std::size_t &start_state_, ";
+        }
+
+        if (sm_._seen_BOL_assertion || !optimize_parameters)
+        {
+	          os_ << "Iterator const& start_, ";
+        }
+
+        if (dfas_ > 1 || sm_._seen_BOL_assertion || !optimize_parameters)
+        {
+            os_ << "\n    ";
+        }
+      
+	      os_ << "Iterator &start_token_, Iterator const& end_)\n";
+	      os_ << "{\n";
+	      os_ << "    enum {end_state_index, id_index, state_index, bol_index, "
+		      "eol_index,\n";
+	      os_ << "        dead_state_index, dfa_offset};\n";
+	      os_ << "    static const std::size_t npos = static_cast"
+		      "<std::size_t>(~0);\n";
+
+	      if (dfas_ > 1)
+	      {
+            for (std::size_t state_ = 0; state_ < dfas_; ++state_)
+            {
+                std::size_t i_ = 0;
+                std::size_t j_ = 1;
+                std::size_t count_ = lookups_ / 8;
+			          std::size_t const* lookup_ = &sm_._lookup[state_]->front ();
+			          std::size_t const* dfa_ = &sm_._dfa[state_]->front ();
+
+			          os_ << "    static const std::size_t lookup" << state_ 
+			              << "_[" << lookups_ << "] = {";
+
+                for (/**/; i_ < count_; ++i_)
+                {
+                    const std::size_t index_ = i_ * 8;
+
+                    os_ << lookup_[index_];
+
+                    for (; j_ < 8; ++j_)
+                    {
+                        os_ << ", " << lookup_[index_ + j_];
+                    }
+
+                    if (i_ < count_ - 1)
+                    {
+                        os_ << "," << std::endl << "        ";
+                    }
+
+                    j_ = 1;
+                }
+
+                os_ << "};\n";
+                count_ = sm_._dfa[state_]->size ();
+                os_ << "    static const std::size_t dfa" << state_ << "_[" <<
+                    count_ << "] = {";
+                count_ /= 8;
+
+                for (i_ = 0; i_ < count_; ++i_)
+                {
+                    const std::size_t index_ = i_ * 8;
+
+                    os_ << dfa_[index_];
+
+                    for (j_ = 1; j_ < 8; ++j_)
+                    {
+                        os_ << ", " << dfa_[index_ + j_];
+                    }
+
+                    if (i_ < count_ - 1)
+                    {
+                        os_ << "," << std::endl << "        ";
+                    }
+                }
+
+                std::size_t const mod_ = sm_._dfa[state_]->size () % 8;
+                if (mod_)
+                {
+                    const std::size_t index_ = count_ * 8;
+
+                    if (count_)
+                    {
+                        os_ << ",\n        ";
+                    }
+
+                    os_ << dfa_[index_];
+
+                    for (j_ = 1; j_ < mod_; ++j_)
+                    {
+                        os_ << ", " << dfa_[index_ + j_];
+                    }
+                }
+
+                os_ << "};\n";
+            }
+
+            std::size_t count_ = sm_._dfa_alphabet.size();
+            std::size_t i_ = 1;
+
+            os_ << "    static const std::size_t *lookup_arr_[" << count_ <<
+                "] = {";
+
+            os_ << "lookup0_";
+
+            for (i_ = 1; i_ < count_; ++i_)
+            {
+                os_ << ", " << "lookup" << i_ << "_";
+            }
+
+            os_ << "};\n";
+            os_ << "    static const std::size_t dfa_alphabet_arr_[" << 
+                count_ << "] = {";
+
+            os_ << sm_._dfa_alphabet.front ();
+
+            for (i_ = 1; i_ < count_; ++i_)
+            {
+                os_ << ", " << sm_._dfa_alphabet[i_];
+            }
+
+            os_ << "};\n";
+            os_ << "    static const std::size_t *dfa_arr_[" << count_ <<
+                "] = {";
+            os_ << "dfa0_";
+
+            for (i_ = 1; i_ < count_; ++i_)
+            {
+                os_ << ", " << "dfa" << i_ << "_";
+            }
+
+            os_ << "};\n";
+	      }
+	      else
+	      {
+		        std::size_t const* lookup_ = &sm_._lookup[0]->front();
+		        std::size_t const* dfa_ = &sm_._dfa[0]->front();
+            std::size_t i_ = 0;
+            std::size_t j_ = 1;
+            std::size_t count_ = lookups_ / 8;
+
+		        os_ << "    static const std::size_t lookup_[";
+		        os_ << sm_._lookup[0]->size() << "] = {";
+
+		        for (; i_ < count_; ++i_)
+            {
+                const std::size_t index_ = i_ * 8;
+
+                os_ << lookup_[index_];
+
+                for (; j_ < 8; ++j_)
+                {
+                    os_ << ", " << lookup_[index_ + j_];
+                }
+
+                if (i_ < count_ - 1)
+                {
+                    os_ << "," << std::endl << "        ";
+                }
+
+                j_ = 1;
+            }
+
+		        os_ << "};\n";
+		        os_ << "    static const std::size_t dfa_alphabet_ = " <<
+			        sm_._dfa_alphabet.front () << ";\n";
+		        os_ << "    static const std::size_t dfa_[" <<
+			        sm_._dfa[0]->size () << "] = {";
+                count_ = sm_._dfa[0]->size () / 8;
+
+            for (i_ = 0; i_ < count_; ++i_)
+            {
+                const std::size_t index_ = i_ * 8;
+
+                os_ << dfa_[index_];
+
+                for (j_ = 1; j_ < 8; ++j_)
+                {
+                    os_ << ", " << dfa_[index_ + j_];
+                }
+
+                if (i_ < count_ - 1)
+                {
+                    os_ << "," << std::endl << "        ";
+                }
+            }
+
+            const std::size_t mod_ = sm_._dfa[0]->size () % 8;
+
+            if (mod_)
+            {
+                const std::size_t index_ = count_ * 8;
+
+                if (count_)
+                {
+                    os_ << ",\n        ";
+                }
+
+                os_ << dfa_[index_];
+
+                for (j_ = 1; j_ < mod_; ++j_)
+                {
+                    os_ << ", " << dfa_[index_ + j_];
+                }
+            }
+
+            os_ << "};\n";
+	      }
+
+	      os_ << "\n    if (start_token_ == end_) return 0;\n\n";
+
+	      if (dfas_ > 1)
+	      {
+		        os_ << "again:\n";
+	          os_ << "    const std::size_t * lookup_ = lookup_arr_[start_state_];\n";
+	          os_ << "    std::size_t dfa_alphabet_ = dfa_alphabet_arr_[start_state_];\n";
+	          os_ << "    const std::size_t *dfa_ = dfa_arr_[start_state_];\n";
+	      }
+
+	      os_ << "    const std::size_t *ptr_ = dfa_ + dfa_alphabet_;\n";
+	      os_ << "    Iterator curr_ = start_token_;\n";
+	      os_ << "    bool end_state_ = *ptr_ != 0;\n";
+	      os_ << "    std::size_t id_ = *(ptr_ + id_index);\n";
+	      os_ << "    Iterator end_token_ = start_token_;\n";
+	      os_ << '\n';
+	      os_ << "    while (curr_ != end_)\n";
+	      os_ << "    {\n";
+
+	      if (sm_._seen_BOL_assertion)
+	      {
+		        os_ << "        std::size_t const BOL_state_ = ptr_[bol_index];\n";
+	      }
+
+	      if (sm_._seen_EOL_assertion)
+	      {
+		        os_ << "        std::size_t const EOL_state_ = ptr_[eol_index];\n";
+	      }
+
+	      if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
+	      {
+		        os_ << '\n';
+	      }
+
+	      if (sm_._seen_BOL_assertion && sm_._seen_EOL_assertion)
+	      {
+		        os_ << "        if (BOL_state_ && (start_token_ == start_ ||\n";
+		        os_ << "            *(start_token_ - 1) == '\\n'))\n";
+		        os_ << "        {\n";
+		        os_ << "            ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+		        os_ << "        else if (EOL_state_ && *curr_ == '\\n')\n";
+		        os_ << "        {\n";
+		        os_ << "            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+		        os_ << "        else\n";
+		        os_ << "        {\n";
+		        os_ << "            std::size_t const state_ =\n";
+
+		        if (lookups_ == 256)
+		        {
+			          os_ << "                ptr_[lookup_[<typename Traits::index_type>"
+			              "(*curr_++)]];\n";
+		        }
+		        else
+		        {
+			          os_ << "                ptr_[lookup_[*curr_++]];\n";
+		        }
+
+		        os_ << '\n';
+		        os_ << "            if (state_ == 0) break;\n";
+		        os_ << '\n';
+		        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+	      }
+	      else if (sm_._seen_BOL_assertion)
+	      {
+		        os_ << "        if (BOL_state_ && (start_token_ == start_ ||\n";
+		        os_ << "            *(start_token_ - 1) == '\\n'))\n";
+		        os_ << "        {\n";
+		        os_ << "            ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+		        os_ << "        else\n";
+		        os_ << "        {\n";
+		        os_ << "            std::size_t const state_ =\n";
+
+		        if (lookups_ == 256)
+		        {
+			          os_ << "                ptr_[lookup_[static_cast<unsigned char>\n";
+			          os_ << "                (*curr_++)]];\n";
+		        }
+		        else
+		        {
+			          os_ << "                ptr_[lookup_[*curr_++]];\n";
+		        }
+
+		        os_ << '\n';
+		        os_ << "            if (state_ == 0) break;\n";
+		        os_ << '\n';
+		        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+	      }
+	      else if (sm_._seen_EOL_assertion)
+	      {
+		        os_ << "        if (EOL_state_ && *curr_ == '\\n')\n";
+		        os_ << "        {\n";
+		        os_ << "            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+		        os_ << "        else\n";
+		        os_ << "        {\n";
+		        os_ << "            std::size_t const state_ =\n";
+
+		        if (lookups_ == 256)
+		        {
+			          os_ << "                ptr_[lookup_[static_cast<unsigned char>\n";
+			          os_ << "                (*curr_++)]];\n";
+		        }
+		        else
+		        {
+			          os_ << "                ptr_[lookup_[*curr_++]];\n";
+		        }
+
+		        os_ << '\n';
+		        os_ << "            if (state_ == 0) break;\n";
+		        os_ << '\n';
+		        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+		        os_ << "        }\n";
+	      }
+	      else
+	      {
+		        os_ << "        std::size_t const state_ =\n";
+
+		        if (lookups_ == 256)
+		        {
+			          os_ << "            ptr_[lookup_[static_cast<unsigned char>\n";
+			          os_ << "            (*curr_++)]];\n";
+		        }
+		        else
+		        {
+			          os_ << "            ptr_[lookup_[*curr_++]];\n";
+		        }
+
+		        os_ << '\n';
+		        os_ << "        if (state_ == 0) break;\n";
+		        os_ << '\n';
+		        os_ << "        ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+	      }
+
+        os_ << '\n';
+        os_ << "        if (*ptr_)\n";
+        os_ << "        {\n";
+        os_ << "            end_state_ = true;\n";
+        os_ << "            id_ = *(ptr_ + id_index);\n";
+
+	      if (dfas_ > 1)
+	      {
+		        os_ << "            start_state_ = *(ptr_ + state_index);\n";
+	      }
+
+	      os_ << "            end_token_ = curr_;\n";
+	      os_ << "        }\n";
+	      os_ << "    }\n";
+	      os_ << '\n';
+
+	      if (sm_._seen_EOL_assertion)
+	      {
+		        os_ << "    const std::size_t EOL_state_ = ptr_[eol_index];\n";
+		        os_ << '\n';
+		        os_ << "    if (EOL_state_ && curr_ == end_)\n";
+		        os_ << "    {\n";
+		        os_ << "        ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+		        os_ << '\n';
+		        os_ << "        if (*ptr_)\n";
+		        os_ << "        {\n";
+		        os_ << "            end_state_ = true;\n";
+		        os_ << "            id_ = *(ptr_ + id_index);\n";
+
+		        if (dfas_ > 1)
+		        {
+			          os_ << "            start_state_ = *(ptr_ + state_index);\n";
+		        }
+
+		        os_ << "            end_token_ = curr_;\n";
+		        os_ << "        }\n";
+		        os_ << "    }\n";
+		        os_ << '\n';
+	      }
+
+	      os_ << "    if (end_state_)\n";
+	      os_ << "    {\n";
+	      os_ << "        // return longest match\n";
+	      os_ << "        start_token_ = end_token_;\n";
+
+	      if (dfas_ > 1)
+	      {
+		        os_ << '\n';
+		        os_ << "        if (id_ == 0) goto again;\n";
+	      }
+
+	      os_ << "    }\n";
+	      os_ << "    else\n";
+	      os_ << "    {\n";
+    	
+	      if (skip_on_nomatch)
+	      {
+	          os_ << "        // No match causes char to be skipped\n";
+	          os_ << "        ++start_token_;\n";
+        }
+      
+	      os_ << "        id_ = npos;\n";
+	      os_ << "    }\n";
+	      os_ << '\n';
+	      os_ << "    return id_;\n";
+	      os_ << "}\n\n";
+
+	      os_ << "}}}}  // namespace boost::spirit::lex::static_\n\n";
+      	
+	      os_ << "#endif\n";
+	      
+        return os_.good();
+    }
+    
+///////////////////////////////////////////////////////////////////////////////
+}}}}   // namespace boost::spirit::lex::detail
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Lexer>
+    inline bool 
+    generate_static(Lexer const& lexer, std::ostream& os, 
+        char const* name_suffix = "")
+    {
+        if (!lexer.get_definition().init_dfa())
+            return false;
+        return detail::generate_cpp(lexer.get_definition().state_machine, 
+            lexer.get_definition().rules, os, name_suffix, false, false);
+    }
+
+///////////////////////////////////////////////////////////////////////////////
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_iterator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,117 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM)
+#define BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp>
+#else
+#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
+#endif
+#include <boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp>
+#include <boost/spirit/home/support/iterators/multi_pass.hpp>
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //  Divide the given functor type into its components (unique and shared) 
+    //  and build a std::pair from these parts
+    template <typename Functor>
+    struct make_functor
+    {
+        typedef 
+            std::pair<typename Functor::unique, typename Functor::shared> 
+        type;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////////
+    //  Divide the given functor type into its components (unique and shared) 
+    //  and build a std::pair from these parts
+    template <typename FunctorData>
+    struct make_multi_pass
+    {
+        typedef  
+            std::pair<typename FunctorData::unique, typename FunctorData::shared> 
+        functor_data_type;
+        typedef typename FunctorData::result_type result_type;
+
+        typedef multi_pass_policies::split_functor_input input_policy;
+        typedef multi_pass_policies::ref_counted ownership_policy;
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+        typedef multi_pass_policies::buf_id_check check_policy;
+#else
+        typedef multi_pass_policies::no_check check_policy;
+#endif
+        typedef multi_pass_policies::split_std_deque storage_policy;
+        
+        typedef multi_pass_policies::default_policy<
+                input_policy, ownership_policy, check_policy, storage_policy>
+            policy_type;
+        typedef spirit::multi_pass<functor_data_type, policy_type> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  lexer_iterator exposes an iterator for a lexertl based dfa (lexer) 
+    //  The template parameters have the same semantics as described for the
+    //  lexertl_functor above.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Functor>
+    class lexertl_iterator
+      : public make_multi_pass<Functor>::type
+    {
+    public:
+        typedef typename Functor::unique unique_functor_type;
+        typedef typename Functor::shared shared_functor_type;
+        
+        typedef typename Functor::iterator_type base_iterator_type;
+        typedef typename Functor::result_type token_type;
+        
+    private:
+        typedef 
+            typename make_multi_pass<Functor>::functor_data_type 
+        functor_type;
+        typedef typename make_multi_pass<Functor>::type base_type;
+        typedef typename Functor::char_type char_type;
+        
+    public:
+        // create a new iterator encapsulating the lexer object to be used
+        // for tokenization
+        template <typename IteratorData>
+        lexertl_iterator(IteratorData const& iterdata_, 
+                base_iterator_type& first, base_iterator_type const& last)
+          : base_type(functor_type(unique_functor_type(), 
+                shared_functor_type(iterdata_, first, last))
+            )
+        {
+        }
+        
+        // create an end iterator usable for end of range checking
+        lexertl_iterator()
+        {}
+        
+        // set the new required state for the underlying lexer object
+        std::size_t set_state(std::size_t state)
+        {
+            return unique_functor_type::set_state(*this, state);
+        }
+        
+        // map the given state name to a corresponding state id as understood
+        // by the underlying lexer object
+        std::size_t map_state(char_type const* statename)
+        {
+            return unique_functor_type::map_state(*this, statename);
+        }
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_lexer.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_lexer.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,356 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXERTL_LEXER_MAR_17_2007_0139PM)
+#define BOOST_SPIRIT_LEX_LEXERTL_LEXER_MAR_17_2007_0139PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <iosfwd>
+
+#include <boost/spirit/home/support/safe_bool.hpp>
+#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_iterator.hpp>
+#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>
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+#include <boost/spirit/home/support/detail/lexer/debug.hpp>
+#endif
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  The must_escape function checks if the given character value needs
+        //  to be preceded by a backslash character to disable its special 
+        //  meaning in the context of a regular expression
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Char>
+        inline bool must_escape(Char c)
+        {
+            // FIXME: more needed?
+            switch (c) {
+            case '+': case '/': case '*': case '?':
+            case '|':
+            case '(': case ')':
+            case '[': case ']':
+            case '{': case '}':
+            case '.':
+            case '^': case '$':
+            case '\\':
+                return true;
+
+            default:
+                break;
+            }
+            return false;
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        //  The escape function returns the string representation of the given 
+        //  character value, possibly escaped with a backslash character, to 
+        //  allow it being safely used in a regular expression definition.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Char>
+        inline std::basic_string<Char> escape(Char ch) 
+        { 
+            std::basic_string<Char> result(1, ch);
+            if (detail::must_escape(ch)) 
+                result.insert(0, 1, '\\');
+            return result;
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  lexertl_token_set
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, typename Iterator = typename Token::iterator_type>
+    class lexertl_token_set
+    {
+    protected:
+        typedef typename 
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+        typedef std::basic_string<char_type> string_type;
+
+    public:
+        // interface for token definition management
+        void add_token (char_type const* state, string_type const& tokendef, 
+            std::size_t token_id)
+        {
+            rules.add(state, tokendef, token_id, state);
+        }
+        
+        // interface for pattern definition management
+        void add_pattern (char_type const* state, string_type const& name,
+            string_type const& patterndef)
+        {
+            add_state(state);
+            rules.add_macro(name.c_str(), patterndef);
+        }
+        
+        boost::lexer::rules const& get_rules() const { return rules; }
+        
+        void clear() { rules.clear(); }
+         
+        std::size_t add_state(char_type const* state)
+        {
+            rules.add_state(state);
+            return rules.state(state);
+        }
+        string_type initial_state() const 
+        { 
+            return string_type(rules.initial());
+        }
+
+    private:
+        boost::lexer::basic_rules<char_type> rules;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Lexer>
+    bool generate_static(Lexer const& lex, std::ostream& os, char const* name);
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  Every lexer type to be used as a lexer for Spirit has to conform to 
+    //  the following public interface:
+    //
+    //    typedefs: 
+    //        iterator_type   The type of the iterator exposed by this lexer.
+    //        token_type      The type of the tokens returned from the exposed 
+    //                        iterators.
+    //        token_set       The type of the token set representing a lexer 
+    //                        state.
+    //
+    //    functions:
+    //        default constructor
+    //                        Since lexers are instantiated as base classes 
+    //                        only it might be a good idea to make this 
+    //                        constructor protected.
+    //        begin, end      Return a pair of iterators, when dereferenced
+    //                        returning the sequence of tokens recognized in 
+    //                        the input stream given as the parameters to the 
+    //                        begin() function.
+    //        add_token       Should add the definition of a token to be 
+    //                        recognized by this lexer.
+    //        clear           Should delete all current token definitions
+    //                        associated with the given state of this lexer 
+    //                        object.
+    //
+    //    template parameters:
+    //        Iterator        The type of the iterator used to access the
+    //                        underlying character stream.
+    //        Token           The type of the tokens to be returned from the
+    //                        exposed token iterator.
+    //        Functor         The type of the InputPolicy to use to instantiate
+    //                        the multi_pass iterator type to be used as the 
+    //                        token iterator (returned from begin()/end()).
+    //        TokenSet        The type of the token set to use in conjunction 
+    //                        with this lexer type. This is used for the 
+    //                        token_set typedef described above only.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The lexertl_lexer class is a implementation of a Spirit.Lex lexer on 
+    //  top of Ben Hanson's lexertl library as outlined above (For more 
+    //  information about lexertl go here: http://www.benhanson.net/lexertl.html).
+    //
+    //  This class is supposed to be used as the first and only template 
+    //  parameter while instantiating instances of a lex::lexer_def class.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Token = lexertl_token<>,
+        typename Iterator = typename Token::iterator_type, 
+        typename Functor = lexertl_functor<Token, Iterator, mpl::false_>,
+        typename TokenSet = token_set<lexertl_token_set<Token, Iterator> >
+    >
+    class lexertl_lexer 
+      : public safe_bool<lexertl_lexer<Token, Iterator, Functor, TokenSet> >
+    {
+    public:
+        // operator_bool() is needed for the safe_bool base class
+        bool operator_bool() const { return initialized_dfa; }
+        
+        typedef typename
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+        typedef std::basic_string<char_type> string_type;
+
+        //  Every lexer type to be used as a lexer for Spirit has to conform to 
+        //  a public interface .
+        typedef Token token_type;
+        typedef TokenSet token_set;
+        typedef lexertl_iterator<Functor> iterator_type;
+        
+        //  Return the start iterator usable for iterating over the generated
+        //  tokens.
+        iterator_type begin(Iterator& first, Iterator const& last) const
+        { 
+            struct iterator_data_type {
+                boost::lexer::state_machine const& state_machine_;
+                boost::lexer::basic_rules<char_type> const& rules_;
+                typename Functor::semantic_actions_type const& actions_;
+            };
+
+            iterator_data_type iterator_data = { state_machine, rules, actions };
+            return init_dfa() ? iterator_type(iterator_data, first, last)
+                              : iterator_type();
+        }
+        
+        //  Return the end iterator usable to stop iterating over the generated 
+        //  tokens.
+        iterator_type end() const
+        { 
+            return iterator_type(); 
+        }
+
+    protected:
+        //  Lexer instances can be created by means of a derived class only.
+        lexertl_lexer()
+          : initialized_dfa(false)
+        {
+        }
+
+    public:
+        // interface for token definition management
+        void add_token (char_type const* state, string_type const& tokendef, 
+            std::size_t token_id)
+        {
+            add_state(state);
+            rules.add(state, tokendef, token_id, state);
+            initialized_dfa = false;
+        }
+        void add_token(char_type const* state, token_set& tokset)
+        {
+            add_state(state);
+            rules.add(state, tokset.get_rules());
+            initialized_dfa = false;
+        }
+        
+        // interface for pattern definition management
+        void add_pattern (char_type const* state, string_type const& name,
+            string_type const& patterndef)
+        {
+            add_state(state);
+            rules.add_macro(name.c_str(), patterndef);
+            initialized_dfa = false;
+        }
+        
+        void clear(char_type const* state)
+        {
+            std::size_t s = rules.state(state);
+            if (boost::lexer::npos != s)
+                rules.clear(state);
+            initialized_dfa = false;
+        }
+        std::size_t add_state(char_type const* state)
+        {
+            std::size_t stateid = rules.state(state);
+            if (boost::lexer::npos == stateid) {
+                rules.add_state(state);
+                stateid = rules.state(state);
+                initialized_dfa = false;
+            }
+            return stateid;
+        }
+        string_type initial_state() const 
+        { 
+            return string_type(rules.initial());
+        }
+        
+        //  Register a semantic action with the given id
+        template <typename F>
+        void add_action(std::size_t id, F act)
+        {
+            // If you get compilation errors below stating value_type not being
+            // a member of boost::fusion::unused_type, then you are probably
+            // using semantic actions in your token definition without 
+            // the lexertl_actor_lexer being specified as the base class 
+            // (instead of the lexertl_lexer class).
+            typedef 
+                typename Functor::semantic_actions_type::value_type
+            value_type;
+            
+            actions.insert(value_type(id, act));
+        }
+                
+        bool init_dfa() const
+        {
+            if (!initialized_dfa) {
+                state_machine.clear();
+                try {
+                    typedef boost::lexer::basic_generator<char_type> generator;
+                    generator::build (rules, state_machine);
+                    generator::minimise (state_machine);
+
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+                    boost::lexer::debug::dump(state_machine, std::cerr);
+#endif
+                }
+                catch (std::runtime_error const&) {
+                    return false;
+                }
+                initialized_dfa = true;
+            }
+            return true;
+        }
+
+    private:
+        mutable boost::lexer::state_machine state_machine;
+        boost::lexer::basic_rules<char_type> rules;
+        typename Functor::semantic_actions_type actions;
+        mutable bool initialized_dfa;
+
+        template <typename Lexer> 
+        friend bool generate_static(Lexer const&, std::ostream&, char const*);
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The lexertl_actor_lexer class is another implementation of a Spirit.Lex 
+    //  lexer on top of Ben Hanson's lexertl library as outlined above (For 
+    //  more information about lexertl go here: 
+    //  http://www.benhanson.net/lexertl.html).
+    //
+    //  The only difference to the lexertl_lexer class above is that token_def
+    //  definitions may have semantic (lexer) actions attached while being 
+    //  defined:
+    //
+    //      int w;
+    //      token_def word = "[^ \t\n]+";
+    //      self = word[++ref(w)];        // see example: word_count_lexer
+    //
+    //  This class is supposed to be used as the first and only template 
+    //  parameter while instantiating instances of a lex::lexer_def class.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Token = lexertl_token<>,
+        typename Iterator = typename Token::iterator_type, 
+        typename Functor = lexertl_functor<Token, Iterator, mpl::true_>,
+        typename TokenSet = token_set<lexertl_token_set<Token, Iterator> >
+    >
+    class lexertl_actor_lexer 
+      : public lexertl_lexer<Token, Iterator, Functor, TokenSet>
+    {
+    protected:
+        //  Lexer instances can be created by means of a derived class only.
+        lexertl_actor_lexer() {}
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,343 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_STATIC_FUNCTOR_FEB_10_2008_0755PM)
+#define BOOST_SPIRIT_LEX_LEXER_STATIC_FUNCTOR_FEB_10_2008_0755PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/mpl/bool.hpp>
+#include <boost/function.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/detail/workaround.hpp>
+#include <map>
+#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/state_machine.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp>
+
+#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+#define BOOST_SPIRIT_EOF_PREFIX static
+#else
+#define BOOST_SPIRIT_EOF_PREFIX 
+#endif
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator, typename HasActors, typename HasState>
+        struct Data;    // no default specialization
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  doesn't support no state and no actors
+        template <typename Iterator>
+        struct Data<Iterator, mpl::false_, mpl::false_>
+        {
+            typedef iterator_range<Iterator> iterpair_type;
+            typedef typename 
+                boost::detail::iterator_traits<Iterator>::value_type 
+            char_type;
+            
+            typedef std::size_t (*next_token_functor)(std::size_t&, 
+                Iterator const&, Iterator&, Iterator const&);
+
+            typedef unused_type semantic_actions_type;
+
+            // initialize the shared data 
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : next_token(data_.next_), first(first_), last(last_)
+            {}
+
+            std::size_t next(Iterator& end)
+            {
+                typedef basic_iterator_tokeniser<Iterator> tokenizer;
+                std::size_t state;
+                return next_token(state, first, end, last);
+            }
+
+            // nothing to invoke, so this is empty
+            bool invoke_actions(std::size_t, Iterator const&) 
+            {
+                return true;    // always accept
+            }
+
+            std::size_t get_state() const { return 0; }
+            void set_state_name (char const*) {}
+
+            next_token_functor next_token;
+            Iterator& first;
+            Iterator last;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  doesn't support no actors
+        template <typename Iterator>
+        struct Data<Iterator, mpl::false_, mpl::true_>
+          : Data<Iterator, mpl::false_, mpl::false_>
+        {
+            typedef Data<Iterator, mpl::false_, mpl::false_> base_type;
+            
+            // initialize the shared data 
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : base_type(data_, first_, last_), state(0)
+            {}
+
+            std::size_t next(Iterator& end)
+            {
+                typedef basic_iterator_tokeniser<Iterator> tokenizer;
+                return this->next_token(state, this->first, end, this->last);
+            }
+
+            std::size_t& get_state() { return state; }
+            void set_state_name (char_type const* new_state) 
+            { 
+                std::size_t state_id = this->rules.state(new_state);
+                BOOST_ASSERT(state_id != boost::lexer::npos);
+                if (state_id != boost::lexer::npos)
+                    state = state_id;
+            }
+
+            std::size_t state;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  does support actors, but may have no state
+        template <typename Iterator, typename HasState>
+        struct Data<Iterator, mpl::true_, HasState> 
+          : Data<Iterator, mpl::false_, HasState>
+        {
+            typedef Data<Iterator, mpl::false_, HasState> base_type;
+            typedef iterator_range<Iterator> iterpair_type;
+            typedef typename 
+                boost::detail::iterator_traits<Iterator>::value_type 
+            char_type;
+
+            typedef void functor_type(iterpair_type, std::size_t, Data&, bool&);
+            typedef boost::function<functor_type> functor_wrapper_type;
+            typedef std::multimap<std::size_t, functor_wrapper_type> 
+                semantic_actions_type;
+
+            template <typename IterData>
+            Data (IterData const& data_, Iterator& first_, Iterator const& last_)
+              : base_type(data_, first_, last_),
+                actions(data_.actions_)
+            {}
+
+            // invoke attached semantic actions, if defined
+            bool invoke_actions(std::size_t id, Iterator const& end)
+            {
+                if (actions.empty()) 
+                    return true;  // nothing to invoke, continue with 'match'
+
+                iterpair_type itp(this->first, end);
+                bool match = true;
+                
+                typedef typename 
+                    semantic_actions_type::const_iterator 
+                iterator_type;
+                
+                std::pair<iterator_type, iterator_type> p = actions.equal_range(id);
+                while (p.first != p.second)
+                {
+                    ((*p.first).second)(itp, id, *this, match);
+                    if (!match)
+                        return false;   // return a 'no-match'
+                    ++p.first;
+                }
+                return true;    // normal execution
+            }
+            
+            semantic_actions_type const& actions;
+        };
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  lexertl_static_functor is a template usable as the functor object for 
+    //  the multi_pass iterator allowing to wrap a lexertl based dfa into a 
+    //  iterator based interface.
+    //  
+    //    Iterator:   the type of the underlying iterator
+    //    Token:      the type of the tokens produced by this functor
+    //                this needs to expose a constructor with the following
+    //                prototype:
+    //
+    //                Token(std::size_t id, std::size_t state, 
+    //                      Iterator start, Iterator end)
+    //
+    //                where 'id' is the token id, state is the lexer state,
+    //                this token has been matched in, and 'first' and 'end'  
+    //                mark the start and the end of the token with respect 
+    //                to the underlying character stream.
+    //    SupportsActors:
+    //                this is expected to be a mpl::bool_, if mpl::true_ the
+    //                lexertl_static_functor invokes functors which 
+    //                (optionally) have been attached to the token definitions.
+    //    SupportState:
+    //                this is expected to be a mpl::bool_, if mpl::true_ the
+    //                lexertl_functor supports different lexer states, 
+    //                otherwise no lexer state is supported.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, 
+        typename Iterator = typename Token::iterator_type, 
+        typename SupportsActors = mpl::false_,
+        typename SupportsState = typename Token::has_state>
+    class lexertl_static_functor
+    {
+    public:
+        typedef typename 
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+
+    private:
+        // Needed by compilers not implementing the resolution to DR45. For
+        // reference, see
+        // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
+        template <typename Iterator_, typename HasActors, typename HasState> 
+        friend struct detail::Data;
+
+        // Helper template allowing to assign a value on exit
+        template <typename T>
+        struct assign_on_exit
+        {
+            assign_on_exit(T& dst_, T const& src_)
+              : dst(dst_), src(src_)
+            {}
+            ~assign_on_exit()
+            {
+                dst = src;
+            }
+            
+            T& dst;
+            T const& src;
+        };
+        
+    public:
+        lexertl_static_functor()
+#if 0 != __DECCXX_VER || BOOST_INTEL_CXX_VERSION > 900
+          , eof()
+#endif // 0 != __DECCXX_VER
+        {}
+        
+        ///////////////////////////////////////////////////////////////////////
+        // interface to the multi_pass_policies::split_functor_input policy
+        typedef Token result_type;
+        typedef lexertl_static_functor unique;
+        typedef detail::Data<Iterator, SupportsActors, SupportsState> shared;
+        
+        BOOST_SPIRIT_EOF_PREFIX result_type const eof;
+    
+        ///////////////////////////////////////////////////////////////////////
+        typedef Iterator iterator_type;
+        typedef typename shared::semantic_actions_type semantic_actions_type;
+        typedef typename shared::next_token_functor next_token_functor;
+
+        template <typename MultiPass>
+        result_type& operator()(MultiPass& mp, result_type& result)
+        {
+            shared& data = mp.shared->ftor;
+            if (data.first == data.last) 
+                return result = eof;
+
+            Iterator end = data.first;
+            std::size_t id = data.next(end);
+            
+            if (boost::lexer::npos == id) {   // no match
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+                std::string next;
+                Iterator it = data.first;
+                for (std::size_t i = 0; i < 10 && it != data.last; ++it, ++i)
+                    next += *it;
+
+                std::cerr << "Not matched, in state: " << data.state 
+                          << ", lookahead: >" << next << "<" << std::endl;
+#endif
+                return result = result_type(0);
+            }
+            else if (0 == id) {         // EOF reached
+                return result = eof;
+            }
+            
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+            {
+                std::string next;
+                Iterator it = data.first;
+                for (std::size_t i = 0; i < 10 && it != data.last; ++it, ++i)
+                    next += *it;
+
+                std::cerr << "Matched: " << id << ", in state: " 
+                          << data.state << ", string: >" 
+                          << std::basic_string<char_type>(data.first, end) << "<"
+                          << ", lookahead: >" << next << "<" << std::endl;
+            }
+#endif
+            // invoke_actions might change state
+            std::size_t state = data.get_state();
+
+            // invoke attached semantic actions, if there are any defined
+            if (!data.invoke_actions(id, end))
+            {
+                // one of the semantic actions signaled no-match
+                return result = result_type(0); 
+            }
+            
+            // return matched token, advancing 'data.first' past the matched 
+            // sequence
+            assign_on_exit<Iterator> on_exit(data.first, end);
+            return result = result_type(id, state, data.first, end);
+        }
+
+        // set_state is propagated up to the iterator interface, allowing to 
+        // manipulate the current lexer state through any of the exposed 
+        // iterators.
+        template <typename MultiPass>
+        static std::size_t set_state(MultiPass& mp, std::size_t state_) 
+        { 
+            std::size_t oldstate = mp.shared->ftor.state;
+            mp.shared->ftor.state = state_;
+
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+            std::cerr << "Switching state from: " << oldstate 
+                      << " to: " << state_
+                      << std::endl;
+#endif
+            return oldstate; 
+        }
+        
+        template <typename MultiPass>
+        static std::size_t 
+        map_state(MultiPass const& mp, char_type const* statename)  
+        { 
+            return mp.shared->ftor.rules.state(statename);
+        }
+    };
+
+#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+    ///////////////////////////////////////////////////////////////////////////
+    //  eof token
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, typename Iterator, typename SupportsActors, 
+        typename SupportsState>
+    typename lexertl_static_functor<
+            Token, Iterator, SupportsActors, SupportsState>::result_type const
+        lexertl_static_functor<
+                Token, Iterator, SupportsActors, SupportsState>::eof = 
+            typename lexertl_static_functor<
+                Token, Iterator, SupportsActors, SupportsState>::result_type();
+#endif // 0 != __COMO_VERSION__
+
+}}}
+
+#undef BOOST_SPIRIT_EOF_PREFIX
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_lexer.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_static_lexer.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,299 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXERTL_STATIC_LEXER_FEB_10_2008_0753PM)
+#define BOOST_SPIRIT_LEX_LEXERTL_STATIC_LEXER_FEB_10_2008_0753PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/safe_bool.hpp>
+#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp>
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_iterator.hpp>
+#if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
+#include <boost/spirit/home/support/detail/lexer/debug.hpp>
+#endif
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  The escape function returns the string representation of the given 
+        //  character value, possibly escaped with a backslash character, to 
+        //  allow it being safely used in a regular expression definition.
+        //
+        //  In the case of the static lexer this function does nothing.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Char>
+        inline std::basic_string<Char> escape(Char ch) 
+        { 
+            return std::basic_string<Char>(1, ch);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // forward declaration only
+    namespace static_ 
+    {
+        //  Both items, the table of names and the function to return the next 
+        //  token have to be generated using the function generate_static().
+        //
+        //  This is a forward declaration for the generated static table of 
+        //  valid state names
+        extern char const* const lexer_state_names[];
+
+        //  This is the forward declaration of the generated function to be 
+        //  called to get the next token. 
+        template <typename Iterator>
+        std::size_t next_token (std::size_t& state_, Iterator const& start_, 
+            Iterator ¤t_, Iterator const& end_);
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  lexertl_static_token_set
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Token, typename Iterator = typename Token::iterator_type>
+    class lexertl_static_token_set
+    {
+    protected:
+        typedef typename 
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+        typedef std::basic_string<char_type> string_type;
+
+    public:
+        // interface for token definition management
+        void add_token (char_type const* state, string_type const& tokendef, 
+            std::size_t token_id)
+        {}
+        
+        // interface for pattern definition management
+        void add_pattern (char_type const* state, string_type const& name,
+            string_type const& patterndef)
+        {}
+        
+        void clear() {}
+         
+        std::size_t add_state(char_type const* state)
+        {
+            return 0;
+        }
+        string_type initial_state() const 
+        { 
+            return lex::static_::lexer_state_names[0];
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  Every lexer type to be used as a lexer for Spirit has to conform to 
+    //  the following public interface:
+    //
+    //    typedefs: 
+    //        iterator_type   The type of the iterator exposed by this lexer.
+    //        token_type      The type of the tokens returned from the exposed 
+    //                        iterators.
+    //        token_set       The type of the token set representing a lexer 
+    //                        state.
+    //
+    //    functions:
+    //        default constructor
+    //                        Since lexers are instantiated as base classes 
+    //                        only it might be a good idea to make this 
+    //                        constructor protected.
+    //        begin, end      Return a pair of iterators, when dereferenced
+    //                        returning the sequence of tokens recognized in 
+    //                        the input stream given as the parameters to the 
+    //                        begin() function.
+    //        add_token       Should add the definition of a token to be 
+    //                        recognized by this lexer.
+    //        clear           Should delete all current token definitions
+    //                        associated with the given state of this lexer 
+    //                        object.
+    //
+    //    template parameters:
+    //        Token           The type of the tokens to be returned from the
+    //                        exposed token iterator.
+    //        Iterator        The type of the iterator used to access the
+    //                        underlying character stream.
+    //        Functor         The type of the InputPolicy to use to instantiate
+    //                        the multi_pass iterator type to be used as the 
+    //                        token iterator (returned from begin()/end()).
+    //        TokenSet        The type of the token set to use in conjunction 
+    //                        with this lexer type. This is used for the 
+    //                        token_set typedef described above only.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The lexertl_static_lexer class is a implementation of a Spirit.Lex 
+    //  lexer on top of Ben Hanson's lexertl library (For more information 
+    //  about lexertl go here: http://www.benhanson.net/lexertl.html). 
+    //
+    //  This class is designed to be used in conjunction with a generated, 
+    //  static lexer. For more information see the documentation (The Static 
+    //  Lexer Model).
+    //
+    //  This class is supposed to be used as the first and only template 
+    //  parameter while instantiating instances of a lex::lexer_def class.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Token = lexertl_token<>,
+        typename Iterator = typename Token::iterator_type, 
+        typename Functor = lexertl_static_functor<Token, Iterator, mpl::false_>,
+        typename TokenSet = token_set<lexertl_static_token_set<Token, Iterator> >
+    >
+    class lexertl_static_lexer 
+      : public safe_bool<lexertl_static_lexer<Token, Iterator, Functor, TokenSet> >
+    {
+    public:
+        // operator_bool() is needed for the safe_bool base class
+        bool operator_bool() const { return true; }
+        
+        typedef typename
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+        typedef std::basic_string<char_type> string_type;
+
+        //  Every lexer type to be used as a lexer for Spirit has to conform to 
+        //  a public interface 
+        typedef Token token_type;
+        typedef TokenSet token_set;
+        typedef lexertl_iterator<Functor> iterator_type;
+        
+        //  Return the start iterator usable for iterating over the generated
+        //  tokens, the Functor F is called to match the next token from the 
+        //  input.
+        template <typename F>
+        iterator_type begin(Iterator& first, Iterator const& last, F next) const
+        { 
+            struct iterator_data_type {
+                typename Functor::next_token_functor next_;
+                typename Functor::semantic_actions_type const& actions_;
+            };
+
+            iterator_data_type iterator_data = { next, actions };
+            return iterator_type(iterator_data, first, last);
+        }
+        
+        //  Return the start iterator usable for iterating over the generated
+        //  tokens, the generated function next_token(...) is called to match 
+        //  the next token from the input.
+        template <typename Iterator_>
+        iterator_type begin(Iterator_& first, Iterator_ const& last) const
+        { 
+            struct iterator_data_type {
+                typename Functor::next_token_functor next_;
+                typename Functor::semantic_actions_type const& actions_;
+            };
+
+            iterator_data_type iterator_data = 
+                { &lex::static_::next_token<Iterator_>, actions };
+            return iterator_type(iterator_data, first, last);
+        }
+
+        //  Return the end iterator usable to stop iterating over the generated 
+        //  tokens.
+        iterator_type end() const
+        { 
+            return iterator_type(); 
+        }
+
+    protected:
+        //  Lexer instances can be created by means of a derived class only.
+        lexertl_static_lexer() {}
+
+    public:
+        // interface for token definition management
+        void add_token (char_type const* state, string_type const& tokendef, 
+            std::size_t token_id)
+        {}
+        void add_token(char_type const* state, token_set& tokset)
+        {}
+        
+        // interface for pattern definition management
+        void add_pattern (char_type const* state, string_type const& name,
+            string_type const& patterndef)
+        {}
+        
+        void clear(char_type const* state) {}
+        
+        std::size_t add_state(char_type const* state)
+        {
+            return 0;
+        }
+        string_type initial_state() const 
+        { 
+            return lex::static_::lexer_state_names[0];
+        }
+        
+        // register a semantic action with the given id
+        template <typename F>
+        void add_action(std::size_t id, F act) 
+        {
+            // If you get compilation errors below stating value_type not being
+            // a member of boost::fusion::unused_type, then you are probably
+            // using semantic actions in your token definition without 
+            // the lexertl_static_actor_lexer being specified as the base class 
+            // (instead of the lexertl_static_lexer class).
+            typedef 
+                typename Functor::semantic_actions_type::value_type
+            value_type;
+            
+            actions.insert(value_type(id, act));
+        }
+
+        bool init_dfa() const { return true; }
+                    
+    private:
+        typename Functor::semantic_actions_type actions;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The lexertl_static_actor_lexer class is another implementation of a 
+    //  Spirit.Lex lexer on top of Ben Hanson's lexertl library as outlined 
+    //  above (For more information about lexertl go here: 
+    //  http://www.benhanson.net/lexertl.html).
+    //
+    //  Just as the lexertl_static_lexer class it is meant to be used with 
+    //  a statically generated lexer as outlined above.
+    //
+    //  The only difference to the lexertl_static_lexer class above is that 
+    //  token_def definitions may have semantic (lexer) actions attached while 
+    //  being defined:
+    //
+    //      int w;
+    //      token_def<> word = "[^ \t\n]+";
+    //      self = word[++ref(w)];        // see example: word_count_lexer
+    //
+    //  This class is supposed to be used as the first and only template 
+    //  parameter while instantiating instances of a lex::lexer_def class.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Token = lexertl_token<>,
+        typename Iterator = typename Token::iterator_type, 
+        typename Functor = lexertl_static_functor<Token, Iterator, mpl::true_>,
+        typename TokenSet = token_set<lexertl_static_token_set<Token, Iterator> >
+    >
+    class lexertl_static_actor_lexer 
+      : public lexertl_static_lexer<Token, Iterator, Functor, TokenSet>
+    {
+    protected:
+        // Lexer instances can be created by means of a derived class only.
+        lexertl_static_actor_lexer() {}
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,424 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXERTL_TOKEN_FEB_10_2008_0751PM)
+#define BOOST_SPIRIT_LEX_LEXERTL_TOKEN_FEB_10_2008_0751PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/insert.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace lex 
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The lexertl_token is the type of the objects returned by default by the 
+    //  lexertl_iterator.
+    //
+    //    template parameters:
+    //        Iterator        The type of the iterator used to access the
+    //                        underlying character stream.
+    //        AttributeTypes  A mpl sequence containing the types of all 
+    //                        required different token values to be supported 
+    //                        by this token type.
+    //        HasState        A mpl::bool_ indicating, whether this token type
+    //                        should support lexer states.
+    //
+    //  It is possible to use other token types with the spirit::lex 
+    //  framework as well. If you plan to use a different type as your token 
+    //  type, you'll need to expose the following things from your token type 
+    //  to make it compatible with spirit::lex:
+    //
+    //    typedefs
+    //        iterator_type   The type of the iterator used to access the
+    //                        underlying character stream.
+    //
+    //    methods
+    //        default constructor
+    //                        This should initialize the token as an end of 
+    //                        input token.
+    //        constructors    The prototype of the other required 
+    //                        constructors should be:
+    //
+    //              token(int)
+    //                        This constructor should initialize the token as 
+    //                        an invalid token (not carrying any specific 
+    //                        values)
+    //
+    //              where:  the int is used as a tag only and its value is 
+    //                      ignored
+    //
+    //                        and:
+    //
+    //              token(std::size_t id, std::size_t state, 
+    //                    iterator_type first, iterator_type last);
+    //
+    //              where:  id:           token id
+    //                      state:        lexer state this token was matched in
+    //                      first, last:  pair of iterators marking the matched 
+    //                                    range in the underlying input stream 
+    //
+    //        accessors
+    //              id()      return the token id of the matched input sequence
+    //
+    //              state()   return the lexer state this token was matched in
+    //
+    //              value()   return the token value
+    //
+    //  Additionally, you will have to implement a couple of helper functions
+    //  in the same namespace as the token type: a comparison operator==() to 
+    //  compare your token instances, a token_is_valid() function and different 
+    //  construct() function overloads as described below.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Iterator = char const*, 
+        typename AttributeTypes = mpl::vector0<>, 
+        typename HasState = mpl::true_
+    >
+    struct lexertl_token;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization of the toke type doesn't contain any item data and
+    //  doesn't support working with lexer states.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    struct lexertl_token<Iterator, omitted, mpl::false_>
+    {
+        typedef Iterator iterator_type;
+        typedef mpl::false_ has_state;
+        
+        //  default constructed tokens correspond to EOI tokens
+        lexertl_token() 
+          : id_(boost::lexer::npos) 
+        {}
+        
+        //  construct an invalid token
+        lexertl_token(int)
+          : id_(0) 
+        {}
+        
+        lexertl_token(std::size_t id, std::size_t)
+          : id_(id)
+        {}
+        
+        lexertl_token(std::size_t id, std::size_t, 
+                Iterator const&, Iterator const&)
+          : id_(id)
+        {}
+        
+        //  this default conversion operator is needed to allow the direct 
+        //  usage of tokens in conjunction with the primitive parsers defined 
+        //  in Qi
+        operator std::size_t() const { return id_; }
+        
+        std::size_t id() const { return id_; }
+        std::size_t state() const { return 0; }   // always '0' (INITIAL state)
+
+    protected:
+        std::size_t id_;         // token id, 0 if nothing has been matched
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This specialization of the toke type doesn't contain any item data but
+    //  supports working with lexer states.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    struct lexertl_token<Iterator, omitted, mpl::true_>
+      : lexertl_token<Iterator, omitted, mpl::false_>
+    {
+    private:
+        typedef lexertl_token<Iterator, omitted, mpl::false_> base_type;
+
+    public:
+        typedef Iterator iterator_type;
+        typedef mpl::true_ has_state;
+
+        //  default constructed tokens correspond to EOI tokens
+        lexertl_token() 
+          : state_(boost::lexer::npos) 
+        {}
+        
+        //  construct an invalid token
+        lexertl_token(int)
+          : base_type(0), state_(boost::lexer::npos) 
+        {}
+        
+        lexertl_token(std::size_t id, std::size_t state)
+          : base_type(id, boost::lexer::npos), state_(state)
+        {}
+        
+        lexertl_token(std::size_t id, std::size_t state, 
+                Iterator const&, Iterator const&)
+          : base_type(id, boost::lexer::npos), state_(state)
+        {}
+        
+        std::size_t state() const { return state_; }
+
+    protected:
+        std::size_t state_;      // lexer state this token was matched in
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The generic version of the lexertl_token type derives from the 
+    //  specialization above and adds a single data member holding the item 
+    //  data carried by the token instance.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  Metafunction to calculate the type of the variant data item to be 
+        //  stored with each token instance.
+        //
+        //  Note: The iterator pair needs to be the first type in the list of 
+        //        types supported by the generated variant type (this is being 
+        //        used to identify whether the stored data item in a particular 
+        //        token instance needs to be converted from the pair of 
+        //        iterators (see the first of the construct() functions below).
+        ///////////////////////////////////////////////////////////////////////
+        template <typename IteratorPair, typename AttributeTypes>
+        struct token_value_typesequence
+        {
+            typedef typename 
+                mpl::insert<
+                    AttributeTypes, 
+                    typename mpl::begin<AttributeTypes>::type, 
+                    IteratorPair
+                >::type
+            sequence_type;
+            typedef typename make_variant_over<sequence_type>::type type;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The type of the data item stored with a token instance is defined 
+        //  by the template parameter 'AttributeTypes' and may be:
+        //  
+        //     omitted:           no data item is stored with the token 
+        //                        instance (this is handled by the 
+        //                        specializations of the lexertl_token class
+        //                        below)
+        //     mpl::vector0<>:    each token instance stores a pair of 
+        //                        iterators pointing to the matched input 
+        //                        sequence
+        //     mpl::vector<...>:  each token instance stores a variant being 
+        //                        able to store the pair of iterators pointing 
+        //                        to the matched input sequence, or any of the 
+        //                        types a specified in the mpl::vector<>
+        //
+        //  All this is done to ensure the token type is as small (in terms 
+        //  of its byte-size) as possible.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename IteratorPair, typename AttributeTypes>
+        struct token_value_type
+        {
+            typedef 
+                typename mpl::eval_if<
+                    is_same<AttributeTypes, mpl::vector0<> >,
+                    mpl::identity<IteratorPair>,
+                    token_value_typesequence<IteratorPair, AttributeTypes>
+                >::type 
+            type;
+        };
+    }
+
+    template <typename Iterator, typename AttributeTypes, typename HasState>
+    struct lexertl_token : lexertl_token<Iterator, omitted, HasState>
+    {
+    private: // precondition assertions
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+        BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value || 
+                            is_same<AttributeTypes, omitted>::value));
+#endif
+        typedef lexertl_token<Iterator, omitted, HasState> base_type;
+        
+    protected: 
+        //  If no additional token value types are given, the the token will 
+        //  hold the plain pair of iterators pointing to the matched range
+        //  in the underlying input sequence. Otherwise the token value is 
+        //  stored as a variant and will again hold the pair of iterators but
+        //  is able to hold any of the given data types as well. The conversion 
+        //  from the iterator pair to the required data type is done when it is
+        //  accessed for the first time.
+        typedef iterator_range<Iterator> iterpair_type;
+        typedef 
+            typename detail::token_value_type<iterpair_type, AttributeTypes>::type 
+        token_value_type;
+
+    public:
+        typedef Iterator iterator_type;
+
+        //  default constructed tokens correspond to EOI tokens
+        lexertl_token() 
+          : value_(iterpair_type(iterator_type(), iterator_type())) 
+        {}
+        
+        //  construct an invalid token
+        lexertl_token(int)
+          : base_type(0), value_(iterpair_type(iterator_type(), iterator_type())) 
+        {}
+        
+        lexertl_token(std::size_t id, std::size_t state, 
+                Iterator first, Iterator last)
+          : base_type(id, state), value_(iterpair_type(first, last))
+        {}
+
+        token_value_type& value() { return value_; }
+        token_value_type const& value() const { return value_; }
+        
+    protected:
+        token_value_type value_; // token value, by default a pair of iterators
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  tokens are considered equal, if their id's match (these are unique)
+    template <typename Iterator, typename AttributeTypes, typename HasState>
+    inline bool 
+    operator== (lexertl_token<Iterator, AttributeTypes, HasState> const& lhs, 
+                lexertl_token<Iterator, AttributeTypes, HasState> const& rhs)
+    {
+        return lhs.id() == rhs.id();
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This overload is needed by the multi_pass/functor_input_policy to 
+    //  validate a token instance. It has to be defined in the same namespace 
+    //  as the token class itself to allow ADL to find it.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename AttributeTypes, typename HasState>
+    inline bool 
+    token_is_valid(lexertl_token<Iterator, AttributeTypes, HasState> const& t)
+    {
+        return 0 != t.id() && std::size_t(boost::lexer::npos) != t.id();
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  We have to provide overloads for the construct() function allowing
+    //  to extract the needed value from the token. These overloads have to be
+    //  defined in the same namespace as the token class itself to allow ADL to 
+    //  find them.
+    ///////////////////////////////////////////////////////////////////////////
+    
+    //  This is called from the parse function of token_def if the token_def
+    //  has been defined to carry a special attribute type
+    template <typename Attribute, typename Iterator, typename AttributeTypes,
+        typename HasState>
+    inline void construct(Attribute& attr, 
+        lexertl_token<Iterator, AttributeTypes, HasState>& t)
+    {
+    //  The goal of this function is to avoid the conversion of the pair of
+    //  iterators (to the matched character sequence) into the token value 
+    //  of the required type being done more than once. For this purpose it 
+    //  checks whether the stored value type is still the default one (pair 
+    //  of iterators) and if yes, replaces the pair of iterators with the 
+    //  converted value to be returned from subsequent calls.
+        
+        if (0 == t.value().which()) {
+        //  first access to the token value
+            typedef iterator_range<Iterator> iterpair_type;
+            iterpair_type const& ip = get<iterpair_type>(t.value());
+            
+        // Interestingly enough we use the assign_to() framework defined in 
+        // Spirit.Qi allowing to convert the pair of iterators to almost any 
+        // required type (assign_to(), if available, uses the standard Spirit 
+        // parsers to do the conversion, and falls back to boost::lexical_cast
+        // otherwise).
+            qi::detail::assign_to(ip.begin(), ip.end(), attr);
+
+        //  If you get an error during the compilation of the following 
+        //  assignment expression, you probably forgot to list one or more 
+        //  types used as token value types (in your token_def<...> 
+        //  definitions) in your definition of the token class. I.e. any token 
+        //  value type used for a token_def<...> definition has to be listed 
+        //  during the declaration of the token type to use. For instance let's 
+        //  assume we have two token_def's:
+        //
+        //      token_def<int> number; number = "...";
+        //      token_def<std::string> identifier; identifier = "...";
+        //
+        //  Then you'll have to use the following token type definition 
+        //  (assuming you are using the lexertl_token class):
+        //
+        //      typedef mpl::vector<int, std::string> token_values;
+        //      typedef lexertl_token<base_iter_type, token_values> token_type;
+        //
+        //  where: base_iter_type is the iterator type used to expose the 
+        //         underlying input stream.
+        //
+        //  This token_type has to be used as the second template parameter 
+        //  to the lexer class:
+        //
+        //      typedef lexertl_lexer<base_iter_type, token_type> lexer_type;
+        //
+        //  again, assuming you're using the lexertl_lexer<> template for your 
+        //  tokenization.
+        
+            t.value() = attr;   // re-assign value
+        }
+        else {
+        // reuse the already assigned value
+            qi::detail::assign_to(get<Attribute>(t.value()), attr);
+        }
+    }
+    
+    //  This is called from the parse function of token_def if the token type
+    //  has no special attribute type assigned 
+    template <typename Attribute, typename Iterator, typename HasState>
+    inline void construct(Attribute& attr, 
+        lexertl_token<Iterator, mpl::vector0<>, HasState>& t)
+    {
+    //  The default type returned by the token_def parser component (if it
+    //  has no token value type assigned) is the pair of iterators to the 
+    //  matched character sequence.
+        
+        qi::detail::assign_to(t.value().begin(), t.value().end(), attr);
+    }
+    
+    //  This is called from the parse function of token_def if the token type
+    //  has been explicitly omitted (i.e. no attribute value is used), which
+    //  essentially means that every attribute gets initialized using default 
+    //  constructed values.
+    template <typename Attribute, typename Iterator, typename HasState>
+    inline void
+    construct(Attribute& attr, lexertl_token<Iterator, omitted, HasState>& t)
+    {
+    }
+    
+    //  This is called from the parse function of token_set or lexer_def_
+    template <typename Iterator, typename AttributeTypes, typename HasState>
+    inline void
+    construct(fusion::vector<std::size_t, iterator_range<Iterator> >& attr,
+        lexertl_token<Iterator, AttributeTypes, HasState> const& t)
+    {
+    //  The type returned by the token_set and lexer_def_ parser components
+    //  is a fusion::vector containing the token id of the matched token 
+    //  and the pair of iterators to the matched character sequence.
+        
+        typedef iterator_range<Iterator> iterpair_type;
+        typedef 
+            fusion::vector<std::size_t, iterator_range<Iterator> > 
+        attribute_type;
+        
+        iterpair_type const& ip = get<iterpair_type>(t.value());
+        attr = attribute_type(t.id(), get<iterpair_type>(t.value()));
+    }
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,156 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXER_META_GRAMMAR_MAR_22_2007_0548PM)
+#define BOOST_SPIRIT_LEX_LEXER_META_GRAMMAR_MAR_22_2007_0548PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/domain.hpp>
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forward declarations
+    ///////////////////////////////////////////////////////////////////////////
+    struct terminal_director;
+    struct sequence;
+    struct action;
+    struct string_token_def;
+    struct char_token_def;
+    
+    template<typename Attribute, typename Char>
+    class token_def;
+
+    template <typename TokenSet>
+    class token_set;
+
+    struct lexer_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  main lexer_meta_grammar in the lex namespace
+    ///////////////////////////////////////////////////////////////////////////
+
+    struct token_def_meta_grammar
+      : proto::or_<
+            // token_def<>
+            meta_grammar::terminal_rule<
+                lex::domain, 
+                terminal_holder<proto::_, lex::token_def<proto::_, proto::_> >, 
+                terminal_director
+            >,
+            // token_set
+            meta_grammar::terminal_rule<
+                lex::domain, 
+                terminal_holder<proto::_, lex::token_set<proto::_> >, 
+                terminal_director
+            >
+        >
+    {
+    };
+    
+    // 'x', L'x', "x", L"x", std::string, std::wstring
+    struct literal_token_def_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                lex::domain, char, char_token_def
+            >,
+            meta_grammar::terminal_rule<
+                lex::domain, wchar_t, char_token_def
+            >,
+            meta_grammar::terminal_rule<
+                lex::domain, char const*, string_token_def 
+            >,
+            meta_grammar::terminal_rule<
+                lex::domain, wchar_t const*, string_token_def 
+            >,
+            meta_grammar::terminal_rule<
+                lex::domain,
+                std::basic_string<char, proto::_, proto::_>,
+                string_token_def 
+            >,
+            meta_grammar::terminal_rule<
+                lex::domain,
+                std::basic_string<wchar_t, proto::_, proto::_>,
+                string_token_def 
+            >
+        >
+    {
+    };
+    
+    struct action_lexer_meta_grammar
+      : proto::or_<
+            // semantic actions for tokens
+            meta_grammar::binary_rule<
+                lex::domain, proto::tag::subscript, action,
+                token_def_meta_grammar, proto::when<proto::_, proto::_arg>
+            >,
+            meta_grammar::binary_rule<
+                lex::domain, proto::tag::subscript, action,
+                action_lexer_meta_grammar, proto::when<proto::_, proto::_arg>
+            >
+        >
+    {
+    };
+    
+    struct lexer_meta_grammar
+      : proto::or_<
+            // token_def<>, ' ', L' ', "...", L"...", std::string, std::wstring
+            token_def_meta_grammar,
+            literal_token_def_meta_grammar,
+            // token_def[...]
+            action_lexer_meta_grammar,
+            // sequence delimited by '|'
+            meta_grammar::binary_rule_flat<
+                lex::domain, proto::tag::bitwise_or, sequence,
+                lexer_meta_grammar
+            >
+        >
+    {
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Lex meta-grammar.
+    //  (see lex/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, lexer_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, lexer_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<lexer_meta_grammar>
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,32 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_LEX_SEQUENCE_MAR_28_2007_0610PM)
+#define SPIRIT_LEX_SEQUENCE_MAR_28_2007_0610PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/lexer/detail/sequence.hpp>
+#include <boost/fusion/include/any.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    struct sequence
+    {
+        template <typename Component, typename LexerDef, typename String>
+        static void 
+        collect(Component const& component, LexerDef& lexdef, 
+            String const& state)
+        {
+            detail::sequence_collect<LexerDef, String> f (lexdef, state);
+            fusion::any(component.elements, f);
+        }
+    };
+    
+}}} // namespace boost::spirit::lex
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/string_token_def.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/string_token_def.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,36 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_STRING_TOKEN_DEF_MAR_28_2007_0722PM)
+#define BOOST_SPIRIT_LEX_STRING_TOKEN_DEF_MAR_28_2007_0722PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  string_token_def 
+    //      represents a string based token definition
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    struct string_token_def
+    {
+        template <typename Component, typename LexerDef, typename String>
+        static void 
+        collect(Component const& component, LexerDef& lexdef, 
+            String const& state)
+        {
+            lexdef.add_token (state.c_str(), subject(component), next_id());
+        }
+    };
+                
+}}}  // namespace boost::spirit::lex
+
+#endif 
Added: trunk/boost/spirit/home/lex/lexer/terminal_director.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/terminal_director.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,73 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_TERMINAL_DIRECTOR_MAR_22_2007_0846PM)
+#define BOOST_SPIRIT_LEX_TERMINAL_DIRECTOR_MAR_22_2007_0846PM
+
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/spirit/home/lex/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    // this is the director for all lexer related proto terminals
+    struct terminal_director
+    {
+        // Qi interface: return value of the parser
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            terminal_holder;
+            typedef typename terminal_holder::terminal_type terminal_type;
+
+            typedef typename
+                terminal_type::template attribute<
+                    terminal_holder, Context, Iterator
+                >::type
+            type;
+        };
+
+        // Qi interface: parse functionality, delegates back to the
+        // corresponding lexer terminal
+        template <typename Component, typename Iterator, typename Context,
+            typename Skipper, typename Attribute>
+        static bool parse(Component const& component,
+            Iterator& first, Iterator const& last, Context& context,
+            Skipper const& skipper, Attribute& attr)
+        {
+            // main entry point, just forward to the lexer terminal
+            return subject(component).held->parse(
+                first, last, context, skipper, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return subject(component).held->what();
+        }
+
+        // Lex interface: collect functionality, delegates back to the
+        // corresponding lexer terminal
+        template <typename Component, typename LexerDef, typename String>
+        static void collect (Component const& component, LexerDef& lexdef,
+            String const& state)
+        {
+            subject(component).held->collect(lexdef, state);
+        }
+
+        // Lex interface: return the token id of the associated token_def
+        template <typename Component>
+        static std::size_t id(Component const& component)
+        {
+            return subject(component).held->id();
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/terminal_holder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/terminal_holder.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,29 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//  Copyright (c) 2001-2007 Joel de Guzman
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_TERMINAL_HOLDER_MAR_22_2007_0217PM)
+#define BOOST_SPIRIT_LEX_TERMINAL_HOLDER_MAR_22_2007_0217PM
+
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    template <typename T, typename Terminal>
+    struct terminal_holder
+    {
+        typedef Terminal terminal_type;
+        T held;
+    };
+
+    template <typename T, typename Terminal>
+    struct make_terminal_holder
+      : proto::terminal<terminal_holder<T, Terminal> >
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/token_def.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/token_def.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,183 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_TOKEN_DEF_MAR_13_2007_0145PM)
+#define BOOST_SPIRIT_LEX_TOKEN_DEF_MAR_13_2007_0145PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/detail/construct.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <string>
+#include <cstdlib>
+
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  create a unique token id, note this is not thread safe
+    ///////////////////////////////////////////////////////////////////////////
+    enum tokenids {
+        // this is the first token id automatically assigned by the library
+        // if needed
+        min_token_id = 0x10000
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    inline std::size_t next_id()
+    {
+        static std::size_t next_token_id = min_token_id;
+        return next_token_id++;   
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  This component represents a token definition
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Attribute, typename Char>
+    class token_def
+      : public proto::extends<
+            typename make_terminal_holder<
+                token_def<Attribute, Char>*, token_def<Attribute, Char>
+            >::type,
+            token_def<Attribute, Char>
+        >
+    {
+    private:
+        // initialize proto base class
+        typedef terminal_holder<token_def*, token_def> terminal_holder;
+        typedef typename proto::terminal<terminal_holder>::type tag;
+        typedef proto::extends<tag, token_def> base_type;
+
+        tag make_tag() 
+        {
+            tag xpr = {{ this }};
+            return xpr;
+        }
+
+    public:
+        // Qi interface: metafunction calculating parser return type
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            //  The return value of the token_def is either the specified 
+            //  attribute type, or the pair of iterators from the match of the 
+            //  corresponding token (if no attribute type has been specified),
+            //  or unused_type (if omitted has been specified).
+            typedef typename Iterator::base_iterator_type iterator_type;
+            typedef typename
+                mpl::if_<
+                    is_same<Attribute, unused_type>,
+                    iterator_range<iterator_type>,
+                    typename mpl::if_<
+                        is_same<Attribute, omitted>,
+                        unused_type,
+                        Attribute
+                    >::type
+                >::type
+            type;
+        };
+
+    private:
+        // Qi interface: parse functionality
+        template <typename Iterator, typename Context, typename Skipper, 
+            typename Attribute1>
+        bool parse(Iterator& first, Iterator const& last, 
+            Context& /*context*/, Skipper const& skipper, Attribute1& attr) const
+        {
+            qi::skip(first, last, skipper);   // always do a pre-skip
+
+            if (first != last) {
+                typedef typename 
+                    boost::detail::iterator_traits<Iterator>::value_type 
+                token_type;
+
+                //  If the following assertion fires you probably forgot to  
+                //  associate this token definition with a lexer instance.
+                BOOST_ASSERT((std::size_t)(~0) != token_state);
+
+                token_type &t = *first;
+                if (token_id == t.id() && token_state == t.state()) {
+                    qi::detail::assign_to(t, attr);
+                    ++first;
+                    return true;
+                }
+            }
+            return false;
+        }
+        friend struct terminal_director;
+        
+        std::string what() const
+        {
+            std::string result = "token_def(\"";
+            result += def;
+            result += "\")";
+            return result;
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        // Lex interface: collect token definitions and put it into the 
+        // provided lexer def
+        template <typename LexerDef, typename String>
+        void collect(LexerDef& lexdef, String const& state)
+        {
+            token_state = lexdef.add_state(state.c_str());
+            if (0 == token_id)
+                token_id = next_id();
+            lexdef.add_token (state.c_str(), def, token_id);
+        }
+            
+    public:
+        typedef Char char_type;
+        typedef std::basic_string<char_type> string_type;
+        
+        // Lex interface: constructing token definitions
+        token_def() 
+          : base_type(make_tag()), token_id(0), token_state(~0) 
+        {}
+        explicit token_def(char_type def_, std::size_t id_ = 0)
+          : base_type(make_tag()), def(lex::detail::escape(def_)), 
+            token_id(0 == id_ ? def_ : id_), token_state(~0) 
+        {}
+        explicit token_def(string_type def_, std::size_t id_ = 0)
+          : base_type(make_tag()), def(def_), token_id(id_), token_state(~0) 
+        {}
+        
+        template <typename String>
+        token_def& operator= (String const& definition)
+        {
+            def = definition;
+            token_id = 0;
+            return *this;
+        }
+        token_def& operator= (token_def const& rhs)
+        {
+            def = rhs.def;
+            token_id = rhs.token_id;
+            return *this;
+        }
+        
+        // general accessors 
+        std::size_t id() const { return token_id; }
+        void id(std::size_t id) { token_id = id; }
+        string_type const& definition() const { return def; }
+        std::size_t state() const { return token_state; }
+        
+    private:
+        string_type def;
+        std::size_t token_id;
+        std::size_t token_state;
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer/token_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer/token_set.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,279 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_TOKEN_SET_MAR_13_2007_0145PM)
+#define BOOST_SPIRIT_LEX_TOKEN_SET_MAR_13_2007_0145PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>
+#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>
+#include <boost/spirit/home/lex/lexer/token_def.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <cstdlib>
+
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  token_set
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename TokenSet>
+    class token_set
+      : public TokenSet,
+        public proto::extends<
+            typename make_terminal_holder<
+                token_set<TokenSet>*, token_set<TokenSet>
+            >::type,
+            token_set<TokenSet>
+        >
+    {
+    protected:
+        typedef typename TokenSet::char_type char_type;
+        typedef typename TokenSet::string_type string_type;
+
+    private:
+        // avoid warnings about using 'this' in constructor
+        token_set& this_() { return *this; }
+
+        typedef token_set<TokenSet> self_type;
+        typedef TokenSet base_token_set;
+
+        // initialize proto base class
+        typedef terminal_holder<token_set*, token_set> terminal_holder;
+        typedef typename proto::terminal<terminal_holder>::type tag;
+        typedef proto::extends<tag, token_set> base_type;
+
+        tag make_tag()
+        {
+            tag xpr = {{ this }};
+            return xpr;
+        }
+
+    public:
+        // Qi interface: metafunction calculating parser return type
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            //  the return value of a token set contains the matched token id,
+            //  and the corresponding pair of iterators
+            typedef typename Iterator::base_iterator_type iterator_type;
+            typedef
+                fusion::vector<std::size_t, iterator_range<iterator_type> >
+            type;
+        };
+
+    private:
+        // Qi interface: parse functionality
+        template <typename Iterator, typename Context, typename Skipper,
+            typename Attribute>
+        bool parse(Iterator& first, Iterator const& last,
+            Context& context, Skipper const& skipper, Attribute& attr) const
+        {
+            qi::skip(first, last, skipper);   // always do a pre-skip
+
+            if (first != last) {
+                typedef typename
+                    boost::detail::iterator_traits<Iterator>::value_type
+                token_type;
+
+                //  If the following assertion fires you probably forgot to
+                //  associate this token set definition with a lexer instance.
+                BOOST_ASSERT(~0 != token_state);
+
+                token_type &t = *first;
+                if (0 != t.id() && token_state == t.state()) {
+                // any of the token definitions matched
+                    qi::detail::assign_to(t, attr);
+                    ++first;
+                    return true;
+                }
+            }
+            return false;
+        }
+        friend struct terminal_director;
+
+        static std::string what() 
+        {
+            return "token_set";
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        // Lex interface: collect token definitions and put it into the
+        // provided lexer def
+        template <typename LexerDef, typename String>
+        void collect(LexerDef& lexdef, String const& state)
+        {
+            token_state = lexdef.add_state(state.c_str());
+            lexdef.add_token (state.c_str(), *this);
+        }
+
+        // allow to use the tokset.add("regex1", id1)("regex2", id2);
+        // syntax
+        struct adder
+        {
+            adder(token_set& def_)
+            : def(def_)
+            {}
+
+            adder const&
+            operator()(char_type c, std::size_t token_id = 0) const
+            {
+                if (0 == token_id)
+                    token_id = static_cast<std::size_t>(c);
+                def.add_token (def.initial_state().c_str(),
+                    lex::detail::escape(c), token_id);
+                return *this;
+            }
+            adder const&
+            operator()(string_type const& s, std::size_t token_id = 0) const
+            {
+                if (0 == token_id)
+                    token_id = next_id();
+                def.add_token (def.initial_state().c_str(), s, token_id);
+                return *this;
+            }
+            template <typename Attribute>
+            adder const&
+            operator()(token_def<Attribute, char_type>& tokdef,
+                std::size_t token_id = 0) const
+            {
+                // make sure we have a token id
+                if (0 == token_id) {
+                    if (0 == tokdef.id()) {
+                        token_id = next_id();
+                        tokdef.id(token_id);
+                    }
+                    else {
+                        token_id = tokdef.id();
+                    }
+                }
+                else { 
+                // the following assertion makes sure, that the token_def
+                // instance has not been assigned a different id earlier
+                    BOOST_ASSERT(0 == tokdef.id() || token_id == tokdef.id());
+                    tokdef.id(token_id);
+                }
+
+                def.add_token (def.initial_state().c_str(), tokdef.definition(),
+                    token_id);
+                return *this;
+            }
+            template <typename TokenSet_>
+            adder const&
+            operator()(token_set<TokenSet_> const& tokset) const
+            {
+                def.add_token (def.initial_state().c_str(), tokset);
+                return *this;
+            }
+
+            token_set& def;
+        };
+        friend struct adder;
+
+        // allow to use lexer.self.add_pattern("pattern1", "regex1")(...);
+        // syntax
+        struct pattern_adder
+        {
+            pattern_adder(token_set& def_) 
+            : def(def_)
+            {}
+
+            pattern_adder const&
+            operator()(string_type const& p, string_type const& s) const
+            {
+                def.add_pattern (def.state.c_str(), p, s);
+                return *this;
+            }
+
+            token_set& def;
+        };
+        friend struct pattern_adder;
+            
+    public:
+        ///////////////////////////////////////////////////////////////////
+        template <typename Expr>
+        void define(Expr const& xpr)
+        {
+            typedef typename
+                result_of::as_component<lex::domain, Expr>::type
+            component;
+            typedef typename component::director director;
+
+            component c = spirit::as_component(lex::domain(), xpr);
+            director::collect(c, *this, base_token_set::initial_state());
+        }
+
+        token_set()
+          : base_type(make_tag()), add(this_()), add_pattern(this_()), 
+            token_state(~0)
+        {}
+
+        // allow to assign a token definition expression
+        template <typename Expr>
+        token_set& operator= (Expr const& xpr)
+        {
+            typedef
+                spirit::traits::is_component<lex::domain, Expr>
+            is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_token_definition, ());
+
+            this->clear();
+            define(xpr);
+            return *this;
+        }
+
+        adder add;
+        pattern_adder add_pattern;
+
+    private:
+        std::size_t token_state;
+    };
+
+    // allow to assign a token definition expression
+    template <typename TokenSet, typename Expr>
+    inline token_set<TokenSet>&
+    operator+= (token_set<TokenSet>& tokset, Expr& xpr)
+    {
+        typedef
+            spirit::traits::is_component<lex::domain, Expr>
+        is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_token_definition, ());
+
+        tokset.define(xpr);
+        return tokset;
+    }
+    template <typename TokenSet, typename Expr>
+    inline token_set<TokenSet>&
+    operator+= (token_set<TokenSet>& tokset, Expr const& xpr)
+    {
+        typedef
+            spirit::traits::is_component<lex::domain, Expr>
+        is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_token_definition, ());
+
+        tokset.define(xpr);
+        return tokset;
+    }
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer_lexertl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer_lexertl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_LEXERTL_MAR_17_2007_1008PM)
+#define BOOST_SPIRIT_LEX_LEXERTL_MAR_17_2007_1008PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+//  These includes make available everything needed to use lexertl either 
+//  standalone or as a lexer component for spirit::qi
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_lexer.hpp>
+#include <boost/spirit/home/lex.hpp>
+
+#endif
Added: trunk/boost/spirit/home/lex/lexer_static_lexertl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/lexer_static_lexertl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_STATIC_LEXERTL_FEB_11_2008_1045AM)
+#define BOOST_SPIRIT_LEX_STATIC_LEXERTL_FEB_11_2008_1045AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+//  These includes make available everything needed to use lexertl as a lexer 
+//  component for spirit::qi
+#include <boost/spirit/home/lex/lexer/lexertl/lexertl_static_lexer.hpp>
+#include <boost/spirit/home/lex.hpp>
+
+#endif
Added: trunk/boost/spirit/home/lex/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_META_GRAMMAR_MAR_13_2007_0243PM)
+#define BOOST_SPIRIT_LEX_META_GRAMMAR_MAR_13_2007_0243PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
+#include <boost/spirit/home/lex/domain.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/placeholders.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    // Check if Expr is a valid lexer expression
+    template <typename Expr, typename Enable = void>
+    struct is_valid_expr : mpl::false_ {};
+
+    // Return a suitable transform for the given Expr
+    template <typename Expr, typename Enable = void>
+    struct expr_transform;
+
+    struct main_meta_grammar
+      : meta_grammar::if_transform<
+            is_valid_expr<proto::_>(),
+            expr_transform<proto::_> 
+        >
+    {
+    };
+    
+}}}
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The spirit lexer domain meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    template <>
+    struct grammar<lex::domain>
+    {
+        typedef lex::main_meta_grammar type;
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/qi/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/qi/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,96 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_QI_META_GRAMMAR_NOV_18_2007_1144AM)
+#define BOOST_SPIRIT_LEX_QI_META_GRAMMAR_NOV_18_2007_1144AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forward declarations
+    ///////////////////////////////////////////////////////////////////////////
+    struct main_meta_grammar;
+    struct lexer_meta_grammar;
+
+    struct state_switcher;
+    struct state_switcher_context;
+    
+    struct plain_token;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  main lexer_meta_grammar in the qi namespace
+    ///////////////////////////////////////////////////////////////////////////
+    struct lexer_meta_grammar
+      : proto::or_<
+            // lexer, lexer_def, token_def
+            meta_grammar::terminal_rule<
+                qi::domain, 
+                lex::terminal_holder<proto::_, proto::_>, 
+                lex::terminal_director
+            >,
+            // set_state("..."), set_state(str)
+            meta_grammar::terminal_rule<
+                qi::domain, tag::set_state_tag<proto::_>, state_switcher
+            >,
+            // in_state("...")[], in_state(str)[]
+            meta_grammar::subscript_rule<
+                qi::domain, in_state_tag<proto::_>, state_switcher_context,
+                main_meta_grammar
+            >,
+            // token(id)
+            meta_grammar::function1_rule<
+                qi::domain, tag::token, plain_token, 
+                proto::terminal<proto::convertible_to<int> >
+            >
+        >
+    {
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hook into the Qi meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, lexer_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, lexer_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<lexer_meta_grammar>
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/qi/state/in_state.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/qi/state/in_state.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_IN_STATE_OCT_09_2007_0748PM)
+#define BOOST_SPIRIT_LEX_IN_STATE_OCT_09_2007_0748PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/xpressive/proto/proto.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // This is the tag returned by the in_state function
+    template <typename String>
+    struct in_state_tag 
+    {
+        String name;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // These are the different overloads allowed for the in_state(...) 
+    // construct
+    ///////////////////////////////////////////////////////////////////////////
+    inline proto::terminal<in_state_tag<char const*> >::type
+    in_state(char const *s)
+    {
+        proto::terminal<in_state_tag<char const*> >::type that = {{s}};
+        return that;
+    }
+    
+    inline proto::terminal<in_state_tag<wchar_t const*> >::type
+    in_state(wchar_t const *s)
+    {
+        proto::terminal<in_state_tag<wchar_t const*> >::type that = {{s}};
+        return that;
+    }
+    
+    template <typename Char, typename Traits, typename Allocator>
+    inline proto::terminal<in_state_tag<char const*> >::type
+    in_state(std::basic_string<Char, Traits, Allocator> const& s)
+    {
+        typename proto::terminal<in_state_tag<Char const*> >::type that = 
+            {{s.c_str()}};
+        return that;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // The following is a helper template allowing to use the in_state()[] as 
+    // a skip parser
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Skipper, typename String = char const*>
+    struct in_state_skipper;
+
+    template <typename Skipper>
+    struct in_state_skipper<Skipper, char const*>
+      : proto::subscript<
+            typename proto::terminal<in_state_tag<char const*> >::type,
+            Skipper
+        >::type
+    {};
+
+    template <typename Skipper>
+    struct in_state_skipper<Skipper, wchar_t const*>
+      : proto::subscript<
+            typename proto::terminal<in_state_tag<wchar_t const*> >::type,
+            Skipper
+        >::type
+    {};
+
+    template <typename Skipper, typename Char, typename Traits, typename Allocator>
+    struct in_state_skipper<Skipper, std::basic_string<Char, Traits, Allocator> >
+      : proto::subscript<
+            typename proto::terminal<in_state_tag<Char const*> >::type,
+            Skipper
+        >::type
+    {};
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/qi/state/state_switcher.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/qi/state/state_switcher.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,171 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_STATE_SWITCHER_SEP_23_2007_0714PM)
+#define BOOST_SPIRIT_LEX_STATE_SWITCHER_SEP_23_2007_0714PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/lex/set_state.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/detail/to_narrow.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  parser, which switches the state of the underlying lexer component
+    //  this parser gets used for the set_state(...) construct.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename Iterator>
+        inline std::size_t
+        set_lexer_state(Iterator& it, std::size_t state)
+        {
+            return it.set_state(state);
+        }
+
+        template <typename Iterator, typename Char>
+        inline std::size_t
+        set_lexer_state(Iterator& it, Char const* statename)
+        {
+            std::size_t state = it.map_state(statename);
+
+            //  If the following assertion fires you probably used the
+            //  set_state(...) or in_state(...)[...] lexer state switcher with
+            //  a lexer state name unknown to the lexer (no token definitions
+            //  have been associated with this lexer state).
+            BOOST_ASSERT(static_cast<std::size_t>(~0) != state);
+            return it.set_state(state);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    struct state_switcher
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            qi::skip(first, last, skipper);   // always do a pre-skip
+
+            // just switch the state and return success
+            detail::set_lexer_state(first, spirit::left(component).name);
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result("set_state(\"");
+            result += spirit::detail::to_narrow_string(
+                spirit::left(component).name);
+            result += "\")";
+            return result;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Parser, which switches the state of the underlying lexer component
+    // for the execution of the embedded sub-parser, switching the state back
+    // afterwards. This parser gets used for the in_state(...)[p] construct.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename Iterator>
+        struct reset_state_on_exit
+        {
+            template <typename State>
+            reset_state_on_exit(Iterator& it_, State state_)
+              : it(it_), state(detail::set_lexer_state(it_, state_))
+            {
+            }
+            ~reset_state_on_exit()
+            {
+                // reset the state of the underlying lexer instance
+                it.set_state(state);
+            }
+
+            Iterator& it;
+            std::size_t state;
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    struct state_switcher_context
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, subject_type, Context, Iterator>::type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);   // always do a pre-skip
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            // the state has to be reset at exit in any case
+            detail::reset_state_on_exit<Iterator> guard(
+                first, proto::arg_c<0>(argument1(component)).name);
+
+            return director::parse(spirit::subject(component), first,
+                last, context, skipper, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result("in_state(\"");
+            result += spirit::detail::to_narrow_string(
+                proto::arg_c<0>(argument1(component)).name);
+            result += "\")[";
+
+            typedef typename
+                spirit::result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/qi/utility/plain_token.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/qi/utility/plain_token.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,72 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_PLAIN_TOKEN_NOV_11_2007_0451PM)
+#define BOOST_SPIRIT_LEX_PLAIN_TOKEN_NOV_11_2007_0451PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/lexical_cast.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    struct plain_token
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename Iterator::base_iterator_type iterator_type;
+            typedef iterator_range<iterator_type> type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);   // always do a pre-skip
+            
+            if (first != last) {
+                // simply match the token id with the id this component has 
+                // been initialized with
+                
+                typedef typename 
+                    boost::detail::iterator_traits<Iterator>::value_type 
+                token_type;
+
+                token_type &t = *first;
+                if (fusion::at_c<0>(component.elements) == t.id()) {
+                    qi::detail::assign_to(t, attr);
+                    ++first;
+                    return true;
+                }
+            }
+            return false;
+        }
+        
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result("token(\"");
+            result += lexical_cast<std::string>(
+                fusion::at_c<0>(component.elements));
+            result += "\")";
+            return result;
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/lex/set_state.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/set_state.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,60 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LEX_SET_STATE_FEB_13_2008_0719PM)
+#define BOOST_SPIRIT_LEX_SET_STATE_FEB_13_2008_0719PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/xpressive/proto/proto.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit 
+{
+    namespace tag
+    {
+        ///////////////////////////////////////////////////////////////////////
+        // This is the tag returned by the set_state function
+        template <typename String>
+        struct set_state_tag 
+        {
+            String name;
+        };
+    }
+        
+    ///////////////////////////////////////////////////////////////////////////
+    // These are the different overloads allowed for the set_state(...) 
+    // construct, which is used by qi and by lex for lexer state switching 
+    // from inside a (parser or lexer) semantic action
+    ///////////////////////////////////////////////////////////////////////////
+    inline proto::terminal<tag::set_state_tag<char const*> >::type
+    set_state(char const *s)
+    {
+        proto::terminal<tag::set_state_tag<char const*> >::type that = {{s}};
+        return that;
+    }
+    
+    inline proto::terminal<tag::set_state_tag<wchar_t const*> >::type
+    set_state(wchar_t const *s)
+    {
+        proto::terminal<tag::set_state_tag<wchar_t const*> >::type that = {{s}};
+        return that;
+    }
+    
+    template <typename Char, typename Traits, typename Allocator>
+    inline proto::terminal<tag::set_state_tag<char const*> >::type
+    set_state(std::basic_string<Char, Traits, Allocator> const& s)
+    {
+        typename proto::terminal<tag::set_state_tag<Char const*> >::type that = 
+            {{s.c_str()}};
+        return that;
+    }
+
+///////////////////////////////////////////////////////////////////////////////
+}}
+
+#endif
Added: trunk/boost/spirit/home/lex/tokenize_and_parse.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/lex/tokenize_and_parse.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,313 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_LEXER_PARSE_NOV_17_2007_0246PM)
+#define BOOST_SPIRIT_LEXER_PARSE_NOV_17_2007_0246PM
+
+#include <boost/spirit/home/qi/meta_grammar.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/lex/lexer.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace lex
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The tokenize_and_parse() function is one of the main Spirit API 
+    //  functions. It simplifies using a lexer as the underlying token source
+    //  while parsing a given input sequence.
+    //
+    //  The function takes a pair of iterators spanning the underlying input 
+    //  stream to parse, the lexer object (built from the token definitions) 
+    //  and a parser object (built from the parser grammar definition).
+    //
+    //  The second version of this function additionally takes an attribute to 
+    //  be used as the top level data structure instance the parser should use 
+    //  to store the recognized input to.
+    //
+    //  The function returns true if the parsing succeeded (the given input
+    //  sequence has been successfully matched by the given grammar).
+    //
+    //  first, last:    The pair of iterators spanning the underlying input 
+    //                  sequence to parse. These iterators must at least 
+    //                  conform to the requirements of the std::intput_iterator 
+    //                  category.
+    //                  On exit the iterator 'first' will be updated to the 
+    //                  position right after the last successfully matched 
+    //                  token. 
+    //  lex:            The lexer object (encoding the token definitions) to be
+    //                  used to convert the input sequence into a sequence of 
+    //                  tokens. This token sequence is passed to the parsing 
+    //                  process. The LexerExpr type must conform to the 
+    //                  lexer interface described in the corresponding section
+    //                  of the documentation.
+    //  xpr:            The grammar object (encoding the parser grammar) to be
+    //                  used to match the token sequence generated by the lex 
+    //                  object instance. The ParserExpr type must conform to 
+    //                  the grammar interface described in the corresponding 
+    //                  section of the documentation.
+    //  attr:           The top level attribute passed to the parser. It will 
+    //                  be populated during the parsing of the input sequence.
+    //                  On exit it will hold the 'parser result' corresponding 
+    //                  to the matched input sequence.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename LexerExpr, typename ParserExpr>
+    inline bool
+    tokenize_and_parse(Iterator& first, Iterator last, LexerExpr const& lex,
+        ParserExpr const& xpr)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+        typedef spirit::traits::is_component<qi::domain, ParserExpr> 
+            is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_parser, (iterator_type, ParserExpr));
+
+        typedef typename 
+            result_of::as_component<qi::domain, ParserExpr>::type 
+        component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        iterator_type iter = lex.begin(first, last);
+        return director::parse(c, iter, lex.end(), unused, unused, unused);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename LexerExpr, typename ParserExpr,
+        typename Attribute>
+    inline bool
+    tokenize_and_parse(Iterator& first, Iterator last, LexerExpr const& lex,
+        ParserExpr const& xpr, Attribute& attr)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+        typedef spirit::traits::is_component<qi::domain, ParserExpr> 
+            is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_parser, (iterator_type, ParserExpr));
+
+        typedef typename 
+            result_of::as_component<qi::domain, ParserExpr>::type 
+        component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        iterator_type iter = lex.begin(first, last);
+        return director::parse(c, iter, lex.end(), unused, unused, attr);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The tokenize_and_phrase_parse() function is one of the main Spirit API 
+    //  functions. It simplifies using a lexer as the underlying token source
+    //  while phrase parsing a given input sequence.
+    //
+    //  The function takes a pair of iterators spanning the underlying input 
+    //  stream to parse, the lexer object (built from the token definitions) 
+    //  and a parser object (built from the parser grammar definition). The 
+    //  additional skipper parameter will be used as the skip parser during
+    //  the parsing process.
+    //
+    //  The second version of this function additionally takes an attribute to 
+    //  be used as the top level data structure instance the parser should use 
+    //  to store the recognized input to.
+    //
+    //  The function returns true if the parsing succeeded (the given input
+    //  sequence has been successfully matched by the given grammar).
+    //
+    //  first, last:    The pair of iterators spanning the underlying input 
+    //                  sequence to parse. These iterators must at least 
+    //                  conform to the requirements of the std::intput_iterator 
+    //                  category.
+    //                  On exit the iterator 'first' will be updated to the 
+    //                  position right after the last successfully matched 
+    //                  token. 
+    //  lex:            The lexer object (encoding the token definitions) to be
+    //                  used to convert the input sequence into a sequence of 
+    //                  tokens. This token sequence is passed to the parsing 
+    //                  process. The LexerExpr type must conform to the 
+    //                  lexer interface described in the corresponding section
+    //                  of the documentation.
+    //  xpr:            The grammar object (encoding the parser grammar) to be
+    //                  used to match the token sequence generated by the lex 
+    //                  object instance. The ParserExpr type must conform to 
+    //                  the grammar interface described in the corresponding 
+    //                  section of the documentation.
+    //  attr:           The top level attribute passed to the parser. It will 
+    //                  be populated during the parsing of the input sequence.
+    //                  On exit it will hold the 'parser result' corresponding 
+    //                  to the matched input sequence.
+    //  skipper_:       The skip parser to be used while parsing the given 
+    //                  input sequence. Note, the skip parser will have to 
+    //                  act on the same token sequence as the main parser 
+    //                  'xpr'.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Iterator, typename LexerExpr, typename ParserExpr, 
+        typename Skipper
+    >
+    inline bool
+    tokenize_and_phrase_parse(Iterator& first, Iterator last, 
+        LexerExpr const& lex, ParserExpr const& xpr, Skipper const& skipper_)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+        typedef spirit::traits::is_component<qi::domain, ParserExpr> 
+            expr_is_component;
+        typedef spirit::traits::is_component<qi::domain, Skipper> 
+            skipper_is_component;
+
+        // report invalid expressions error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, 
+            (iterator_type, ParserExpr, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(
+            skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, 
+            (iterator_type, ParserExpr, Skipper));
+
+        typedef typename 
+            result_of::as_component<qi::domain, ParserExpr>::type 
+        component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        typename result_of::as_component<qi::domain, Skipper>::type
+            skipper = spirit::as_component(qi::domain(), skipper_);
+
+        iterator_type iter = lex.begin(first, last);
+        if (!director::parse(c, iter, lex.end(), unused, skipper, unused))
+            return false;
+
+        // do a final post-skip
+        skip(iter, lex.end(), skipper);
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Iterator, typename LexerExpr, typename ParserExpr, 
+        typename Attribute, typename Skipper
+    >
+    inline bool
+    tokenize_and_phrase_parse(Iterator& first, Iterator last, 
+        LexerExpr const& lex, ParserExpr const& xpr, Attribute& attr,
+        Skipper const& skipper_)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+        typedef spirit::traits::is_component<qi::domain, ParserExpr> 
+            expr_is_component;
+        typedef spirit::traits::is_component<qi::domain, Skipper> 
+            skipper_is_component;
+
+        // report invalid expressions error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, 
+            (iterator_type, ParserExpr, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(
+            skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, 
+            (iterator_type, ParserExpr, Skipper));
+
+        typedef typename 
+            result_of::as_component<qi::domain, ParserExpr>::type 
+        component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        typename result_of::as_component<qi::domain, Skipper>::type
+            skipper = spirit::as_component(qi::domain(), skipper_);
+
+        iterator_type iter = lex.begin(first, last);
+        if (!director::parse(c, iter, lex.end(), unused, skipper, attr))
+            return false;
+
+        // do a final post-skip
+        skip(iter, lex.end(), skipper);
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  The tokenize() function is one of the main Spirit API functions. It 
+    //  simplifies using a lexer to tokenize a given input sequence. It's main
+    //  purpose is to use the lexer to tokenize all the input. 
+    
+    //  The second version below discards all generated tokens afterwards. 
+    //  This is useful whenever all the needed functionality has been 
+    //  implemented directly inside the lexer semantic actions, which are being 
+    //  executed while the tokens are matched. 
+    //
+    //  The function takes a pair of iterators spanning the underlying input 
+    //  stream to scan, the lexer object (built from the token definitions),
+    //  and a (optional) functor being call for each of the generated tokens. 
+    //
+    //  The function returns true if the scanning of the input succeeded (the 
+    //  given input sequence has been successfully matched by the given token
+    //  definitions).
+    //
+    //  first, last:    The pair of iterators spanning the underlying input 
+    //                  sequence to parse. These iterators must at least 
+    //                  conform to the requirements of the std::intput_iterator 
+    //                  category.
+    //                  On exit the iterator 'first' will be updated to the 
+    //                  position right after the last successfully matched 
+    //                  token. 
+    //  lex:            The lexer object (encoding the token definitions) to be
+    //                  used to convert the input sequence into a sequence of 
+    //                  tokens. The LexerExpr type must conform to the 
+    //                  lexer interface described in the corresponding section
+    //                  of the documentation.
+    //  f:              A functor (callable object) taking a single argument of
+    //                  the token type and returning a bool, indicating whether
+    //                  the tokenization should be canceled.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename LexerExpr, typename F>
+    inline bool
+    tokenize(Iterator& first, Iterator last, LexerExpr const& lex, F f)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+
+        iterator_type end = lex.end();
+        for (iterator_type iter = lex.begin(first, last); iter != end; ++iter) 
+        {
+            if (!f(*iter))
+                return false;
+        }
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename LexerExpr>
+    inline bool
+    tokenize(Iterator& first, Iterator last, LexerExpr const& lex)
+    {
+        typedef typename LexerExpr::iterator_type iterator_type;
+
+        iterator_type iter = lex.begin(first, last);
+        iterator_type end = lex.end();
+
+        while (iter != end && token_is_valid(*iter))
+            ++iter;
+            
+        return (iter == end) ? true : false;
+    }
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,10 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_PHOENIX_APRIL_11_2008_0850AM)
+#define BOOST_SPIRIT_PHOENIX_APRIL_11_2008_0850AM
+
+#endif
Added: trunk/boost/spirit/home/phoenix/algorithm.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/algorithm.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,14 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_ALGORITHM_HPP
+#define PHOENIX_ALGORITHM_HPP
+
+#include <boost/spirit/home/phoenix/stl/algorithm/iteration.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/querying.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/transformation.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_BIND_HPP
+#define PHOENIX_BIND_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/bind/bind_function.hpp>
+#include <boost/spirit/home/phoenix/bind/bind_function_object.hpp>
+#include <boost/spirit/home/phoenix/bind/bind_member_function.hpp>
+#include <boost/spirit/home/phoenix/bind/bind_member_variable.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind/bind_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/bind_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,58 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_BIND_BIND_FUNCTION_HPP
+#define PHOENIX_BIND_BIND_FUNCTION_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/detail/function_eval.hpp>
+#include <boost/spirit/home/phoenix/bind/detail/function_ptr.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename RT>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<0>
+          , detail::function_ptr<0, RT, RT(*)()>
+        >::type>
+    bind(RT(*f)())
+    {
+        typedef detail::function_ptr<0, RT, RT(*)()> fp_type;
+        return compose<detail::function_eval<0> >(fp_type(f));
+    }
+
+    template <typename RT, typename T0, typename A0>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::function_ptr<1, RT, RT(*)(T0)>
+          , A0
+        >::type>
+    bind(RT(*f)(T0), A0 const& _0)
+    {
+        typedef detail::function_ptr<1, RT, RT(*)(T0)> fp_type;
+        return compose<detail::function_eval<1> >(fp_type(f), _0);
+    }
+
+    template <typename RT, typename T0, typename T1, typename A0, typename A1>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<2>
+          , detail::function_ptr<2, RT, RT(*)(T0, T1)>
+          , A0, A1
+        >::type>
+    bind(RT(*f)(T0, T1), A0 const& _0, A1 const& _1)
+    {
+        typedef detail::function_ptr<2, RT, RT(*)(T0, T1)> fp_type;
+        return compose<detail::function_eval<2> >(fp_type(f), _0, _1);
+    }
+
+    //  Bring in the rest of the function binders
+    #include <boost/spirit/home/phoenix/bind/detail/bind_function.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind/bind_function_object.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/bind_function_object.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,40 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_BIND_BIND_FUNCTION_OBJECT_HPP
+#define PHOENIX_BIND_BIND_FUNCTION_OBJECT_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/detail/function_eval.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename F>
+    inline actor<typename as_composite<detail::function_eval<0>, F>::type>
+    bind(F const& f)
+    {
+        return compose<detail::function_eval<0> >(f);
+    }
+
+    template <typename F, typename A0>
+    inline actor<typename as_composite<detail::function_eval<1>, F, A0>::type>
+    bind(F const& f, A0 const& _0)
+    {
+        return compose<detail::function_eval<1> >(f, _0);
+    }
+
+    template <typename F, typename A0, typename A1>
+    inline actor<typename as_composite<detail::function_eval<2>, F, A0, A1>::type>
+    bind(F const& f, A0 const& _0, A1 const& _1)
+    {
+        return compose<detail::function_eval<2> >(f, _0, _1);
+    }
+
+    //  Bring in the rest of the function object binders
+    #include <boost/spirit/home/phoenix/bind/detail/bind_function_object.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind/bind_member_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/bind_member_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,77 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_BIND_BIND_MEMBER_FUNCTION_HPP
+#define PHOENIX_BIND_BIND_MEMBER_FUNCTION_HPP
+
+#include <boost/spirit/home/phoenix/core/reference.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/detail/function_eval.hpp>
+#include <boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename RT, typename ClassT, typename ClassA>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_function_ptr<0, RT, RT(ClassT::*)()>
+          , ClassA
+        >::type>
+    bind(RT(ClassT::*f)(), ClassA const& obj)
+    {
+        typedef detail::member_function_ptr<0, RT, RT(ClassT::*)()> fp_type;
+        return compose<detail::function_eval<1> >(fp_type(f), obj);
+    }
+
+    template <typename RT, typename ClassT, typename ClassA>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_function_ptr<0, RT, RT(ClassT::*)() const>
+          , ClassA
+        >::type>
+    bind(RT(ClassT::*f)() const, ClassA const& obj)
+    {
+        typedef detail::member_function_ptr<0, RT, RT(ClassT::*)() const> fp_type;
+        return compose<detail::function_eval<1> >(fp_type(f), obj);
+    }
+
+    template <typename RT, typename ClassT>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_function_ptr<0, RT, RT(ClassT::*)()>
+          , actor<reference<ClassT> >
+        >::type>
+    bind(RT(ClassT::*f)(), ClassT& obj)
+    {
+        typedef detail::member_function_ptr<0, RT, RT(ClassT::*)()> fp_type;
+        return compose<detail::function_eval<1> >(
+            fp_type(f)
+          , actor<reference<ClassT> >(reference<ClassT>(obj)));
+    }
+
+    template <typename RT, typename ClassT>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_function_ptr<0, RT, RT(ClassT::*)() const>
+          , actor<reference<ClassT> >
+        >::type>
+    bind(RT(ClassT::*f)() const, ClassT& obj)
+    {
+        typedef detail::member_function_ptr<0, RT, RT(ClassT::*)() const> fp_type;
+        return compose<detail::function_eval<1> >(
+            fp_type(f)
+          , actor<reference<ClassT> >(reference<ClassT>(obj)));
+    }
+
+    //  Bring in the rest of the function binders
+    #include <boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind/bind_member_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/bind_member_variable.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,76 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_BIND_BIND_MEMBER_VARIABLE_HPP
+#define PHOENIX_BIND_BIND_MEMBER_VARIABLE_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/reference.hpp>
+#include <boost/spirit/home/phoenix/core/detail/function_eval.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace detail
+    {
+        template <typename RT, typename MP>
+        struct member_variable
+        {
+            template <typename Class>
+            struct result
+            {
+                typedef RT& type;
+            };
+
+            member_variable(MP mp)
+                : mp(mp) {}
+
+            template <typename Class>
+            RT& operator()(Class& obj) const
+            {
+                return obj.*mp;
+            }
+
+            template <typename Class>
+            RT& operator()(Class* obj) const
+            {
+                return obj->*mp;
+            }
+
+            MP mp;
+        };
+    }
+
+    template <typename RT, typename ClassT, typename ClassA>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_variable<RT, RT ClassT::*>
+          , ClassA
+        >::type>
+    bind(RT ClassT::*mp, ClassA const& obj)
+    {
+        typedef detail::member_variable<RT, RT ClassT::*> mp_type;
+        return compose<detail::function_eval<1> >(mp_type(mp), obj);
+    }
+
+    template <typename RT, typename ClassT>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<1>
+          , detail::member_variable<RT, RT ClassT::*>
+          , actor<reference<ClassT> >
+        >::type>
+    bind(RT ClassT::*mp, ClassT& obj)
+    {
+        typedef detail::member_variable<RT, RT ClassT::*> mp_type;
+        return compose<detail::function_eval<1> >(
+            mp_type(mp)
+          , actor<reference<ClassT> >(reference<ClassT>(obj)));
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/bind/detail/bind_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/detail/bind_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_BIND_DETAIL_BIND_FUNCTION_HPP)
+#define PHOENIX_BIND_DETAIL_BIND_FUNCTION_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT),                              \
+    "boost/spirit/home/phoenix/bind/detail/bind_function.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename RT
+      , BOOST_PP_ENUM_PARAMS(N, typename T)
+      , BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<N>
+          , detail::function_ptr<N, RT, RT(*)(BOOST_PP_ENUM_PARAMS(N, T))>
+          , BOOST_PP_ENUM_PARAMS(N, A)
+        >::type>
+    bind(RT(*f)(BOOST_PP_ENUM_PARAMS(N, T))
+      , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        typedef detail::function_ptr<
+            N, RT, RT(*)(BOOST_PP_ENUM_PARAMS(N, T))> fp_type;
+        return compose<detail::function_eval<N> >(
+            fp_type(f), BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/bind/detail/bind_function_object.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/detail/bind_function_object.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_BIND_DETAIL_BIND_FUNCTION_OBJECT_HPP)
+#define PHOENIX_BIND_DETAIL_BIND_FUNCTION_OBJECT_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT),                              \
+    "boost/spirit/home/phoenix/bind/detail/bind_function_object.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename F, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<typename as_composite<detail::function_eval<N>, F
+      , BOOST_PP_ENUM_PARAMS(N, A)>::type>
+    bind(F const& f, BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        return compose<detail::function_eval<N> >(f, BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,132 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_BIND_DETAIL_BIND_MEMBER_FUNCTION_HPP)
+#define PHOENIX_BIND_DETAIL_BIND_MEMBER_FUNCTION_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/inc.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (1, BOOST_PP_DEC(BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT)),                \
+    "boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename RT
+      , typename ClassT
+      , BOOST_PP_ENUM_PARAMS(N, typename T)
+      , typename ClassA
+      , BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<BOOST_PP_INC(N)>
+          , detail::member_function_ptr<N,
+                RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))>
+          , ClassA, BOOST_PP_ENUM_PARAMS(N, A)
+        >::type>
+    bind(
+        RT(ClassT::*f)(BOOST_PP_ENUM_PARAMS(N, T))
+      , ClassA const& obj
+      , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        typedef detail::member_function_ptr<
+            N, RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))> fp_type;
+        return compose<detail::function_eval<BOOST_PP_INC(N)> >(
+            fp_type(f), obj, BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+    template <typename RT
+      , typename ClassT
+      , BOOST_PP_ENUM_PARAMS(N, typename T)
+      , typename ClassA
+      , BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<BOOST_PP_INC(N)>
+          , detail::member_function_ptr<N,
+                RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const>
+          , ClassA, BOOST_PP_ENUM_PARAMS(N, A)
+        >::type>
+    bind(
+        RT(ClassT::*f)(BOOST_PP_ENUM_PARAMS(N, T)) const
+      , ClassA const& obj
+      , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        typedef detail::member_function_ptr<
+            N, RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const> fp_type;
+        return compose<detail::function_eval<BOOST_PP_INC(N)> >(
+            fp_type(f), obj, BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+    template <typename RT
+      , typename ClassT
+      , BOOST_PP_ENUM_PARAMS(N, typename T)
+      , BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<BOOST_PP_INC(N)>
+          , detail::member_function_ptr<N,
+                RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))>
+          , actor<reference<ClassT> >
+          , BOOST_PP_ENUM_PARAMS(N, A)
+        >::type>
+    bind(
+        RT(ClassT::*f)(BOOST_PP_ENUM_PARAMS(N, T))
+      , ClassT& obj
+      , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        typedef detail::member_function_ptr<
+            N, RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))> fp_type;
+        return compose<detail::function_eval<BOOST_PP_INC(N)> >(
+            fp_type(f)
+          , actor<reference<ClassT> >(reference<ClassT>(obj))
+          , BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+    template <typename RT
+      , typename ClassT
+      , BOOST_PP_ENUM_PARAMS(N, typename T)
+      , BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<
+        typename as_composite<
+            detail::function_eval<BOOST_PP_INC(N)>
+          , detail::member_function_ptr<N,
+                RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const>
+          , actor<reference<ClassT> >
+          , BOOST_PP_ENUM_PARAMS(N, A)
+        >::type>
+    bind(
+        RT(ClassT::*f)(BOOST_PP_ENUM_PARAMS(N, T)) const
+      , ClassT& obj
+      , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        typedef detail::member_function_ptr<
+            N, RT, RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const> fp_type;
+        return compose<detail::function_eval<BOOST_PP_INC(N)> >(
+            fp_type(f)
+          , actor<reference<ClassT> >(reference<ClassT>(obj))
+          , BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/bind/detail/function_ptr.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/detail/function_ptr.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,99 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_BIND_DETAIL_FUNCTION_PTR_HPP)
+#define PHOENIX_BIND_DETAIL_FUNCTION_PTR_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/dec.hpp>
+
+namespace boost { namespace phoenix { namespace detail
+{
+    template <int N>
+    struct function_ptr_impl
+    {
+        template <typename RT, typename FP>
+        struct impl;
+    };
+
+    template <int N, typename RT, typename FP>
+    struct function_ptr : function_ptr_impl<N>::template impl<RT, FP>
+    {
+        typedef typename function_ptr_impl<N>::template impl<RT, FP> base;
+        function_ptr(FP fp)
+            : base(fp) {}
+    };
+
+    template <>
+    struct function_ptr_impl<0>
+    {
+        template <typename RT, typename FP>
+        struct impl
+        {
+            typedef RT result_type;
+
+            impl(FP fp)
+                : fp(fp) {}
+
+            RT operator()() const
+            {
+                return fp();
+            }
+
+            FP fp;
+        };
+    };
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (1, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/bind/detail/function_ptr.hpp"))
+#include BOOST_PP_ITERATE()
+
+}}} // namespace boost::phoenix::detail
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <>
+    struct function_ptr_impl<N>
+    {
+        template <typename RT, typename FP>
+        struct impl
+        {
+            template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+            struct result
+            {
+                typedef RT type;
+            };
+
+            impl(FP fp)
+                : fp(fp) {}
+
+            template <BOOST_PP_ENUM_PARAMS(N, typename A)>
+            RT operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _)) const
+            {
+                return fp(BOOST_PP_ENUM_PARAMS(N, _));
+            }
+
+            FP fp;
+        };
+    };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,119 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_BIND_DETAIL_MEMBER_FUNCTION_PTR_HPP)
+#define PHOENIX_BIND_DETAIL_MEMBER_FUNCTION_PTR_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/utility/addressof.hpp>
+
+namespace boost { namespace phoenix { namespace detail
+{
+    template <int N>
+    struct member_function_ptr_impl
+    {
+        template <typename RT, typename FP>
+        struct impl;
+    };
+
+    template <int N, typename RT, typename FP>
+    struct member_function_ptr
+        : member_function_ptr_impl<N>::template impl<RT, FP>
+    {
+        typedef typename member_function_ptr_impl<N>::
+            template impl<RT, FP> base;
+        member_function_ptr(FP fp)
+            : base(fp) {}
+    };
+
+    template <>
+    struct member_function_ptr_impl<0>
+    {
+        template <typename RT, typename FP>
+        struct impl
+        {
+            template <typename Class>
+            struct result
+            {
+                typedef RT type;
+            };
+
+            impl(FP fp)
+                : fp(fp) {}
+
+            template <typename Class>
+            RT operator()(Class& obj) const
+            {
+                return (obj.*fp)();
+            }
+
+            template <typename Class>
+            RT operator()(Class* obj) const
+            {
+                return (obj->*fp)();
+            }
+
+            FP fp;
+        };
+    };
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (1, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/bind/detail/member_function_ptr.hpp"))
+#include BOOST_PP_ITERATE()
+
+}}} // namespace boost::phoenix::detail
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <>
+    struct member_function_ptr_impl<N>
+    {
+        template <typename RT, typename FP>
+        struct impl
+        {
+            template <typename Class, BOOST_PP_ENUM_PARAMS(N, typename T)>
+            struct result
+            {
+                typedef RT type;
+            };
+
+            impl(FP fp)
+                : fp(fp) {}
+
+            template <typename Class, BOOST_PP_ENUM_PARAMS(N, typename A)>
+            RT operator()(Class& obj, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _)) const
+            {
+                return (obj.*fp)(BOOST_PP_ENUM_PARAMS(N, _));
+            }
+
+            template <typename Class, BOOST_PP_ENUM_PARAMS(N, typename A)>
+            RT operator()(Class* obj, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _)) const
+            {
+                return (obj->*fp)(BOOST_PP_ENUM_PARAMS(N, _));
+            }
+
+            FP fp;
+        };
+    };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/container.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,12 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CONTAINER_HPP
+#define PHOENIX_CONTAINER_HPP
+
+#include <boost/spirit/home/phoenix/stl/container/container.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,23 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_HPP
+#define PHOENIX_CORE_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/basic_environment.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/as_actor.hpp>
+#include <boost/spirit/home/phoenix/core/is_actor.hpp>
+#include <boost/spirit/home/phoenix/core/argument.hpp>
+#include <boost/spirit/home/phoenix/core/value.hpp>
+#include <boost/spirit/home/phoenix/core/reference.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/nothing.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/actor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/actor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,174 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_ACTOR_HPP
+#define PHOENIX_CORE_ACTOR_HPP
+
+#if !defined(BOOST_RESULT_OF_NUM_ARGS)
+# define BOOST_RESULT_OF_NUM_ARGS PHOENIX_ACTOR_LIMIT
+#else
+# if (BOOST_RESULT_OF_NUM_ARGS < PHOENIX_ACTOR_LIMIT)
+#   error "BOOST_RESULT_OF_NUM_ARGS  < PHOENIX_ACTOR_LIMIT"
+# endif
+#endif
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/basic_environment.hpp>
+#include <boost/mpl/min.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/result_of.hpp>
+
+namespace boost { namespace phoenix
+{
+    // phoenix::void_ is the same as fusion::void_
+    typedef fusion::void_ void_;
+    
+    namespace detail
+    {
+        //  Forward declarations. These will come in when we get to the
+        //  operator module, yet, the actor's assignment operator and index
+        //  operator are required to be members.
+
+        template <typename T0, typename T1>
+        struct make_assign_composite;
+
+        template <typename T0, typename T1>
+        struct make_index_composite;
+
+        template <typename BaseT0, typename BaseT1>
+        struct comma_result;
+        
+        // error no arguments supplied
+        struct error_expecting_arguments
+        {
+            template <typename T>
+            error_expecting_arguments(T const&) {}
+        };            
+    }
+
+    template <typename Eval, typename Env>
+    struct eval_result
+    {
+        typedef typename Eval::template result<Env>::type type;
+    };
+
+    template <typename Eval>
+    struct actor : Eval
+    {
+        typedef actor<Eval> self_type;
+        typedef Eval eval_type;
+
+        template <class Sig> struct result {};
+        
+        actor()
+            : Eval() {}
+
+        actor(Eval const& base)
+            : Eval(base) {}
+
+        template <typename T0>
+        explicit actor(T0 const& _0)
+            : Eval(_0) {}
+
+        template <typename T0, typename T1>
+        actor(T0 const& _0, T1 const& _1)
+            : Eval(_0, _1) {}
+
+        typedef typename 
+            mpl::eval_if<
+                typename Eval::no_nullary // avoid calling eval_result when this is true
+              , mpl::identity<detail::error_expecting_arguments>
+              , eval_result<eval_type, basic_environment<> >
+            >::type
+        nullary_result;
+
+        nullary_result 
+        operator()() const
+        {
+            return eval_type::eval(basic_environment<>());
+        }
+
+        template <class F, class A0>
+        struct result<F(A0)>
+          : eval_result<
+                eval_type
+              , basic_environment<
+                    typename remove_reference<typename add_const<A0>::type>::type
+                >
+            >
+        {};
+        
+        template <typename T0>
+        typename result<actor(T0&)>::type
+        operator()(T0& _0) const
+        {
+            return eval_type::eval(basic_environment<T0>(_0));
+        }
+
+        template <class F, class A0, class A1>
+        struct result<F(A0,A1)>
+          : eval_result<
+                eval_type
+              , basic_environment<
+                    typename remove_reference<typename add_const<A0>::type>::type
+                  , typename remove_reference<typename add_const<A1>::type>::type
+                >
+            >
+        {};
+        
+        template <typename T0, typename T1>
+        typename result<actor(T0&,T1&)>::type
+        operator()(T0& _0, T1& _1) const
+        {
+            return eval_type::eval(basic_environment<T0, T1>(_0, _1));
+        }
+        
+        template <typename T1>
+        typename detail::make_assign_composite<self_type, T1>::type
+        operator=(T1 const& a1) const;
+
+        template <typename T1>
+        typename detail::make_index_composite<self_type, T1>::type
+        operator[](T1 const& a1) const;
+
+        //  Bring in the rest of the constructors and function call operators 
+        #include <boost/spirit/home/phoenix/core/detail/actor.hpp>
+    };
+
+    //  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, 
+    //  is not included by the client and the client attempts to use 
+    //  the comma anyway.
+
+    namespace detail
+    {
+        template <typename BaseT0, typename BaseT1>
+        struct comma_result;
+    }
+
+    template <typename BaseT0, typename BaseT1>
+    typename detail::comma_result<BaseT0, BaseT1>::type
+    operator,(actor<BaseT0> const& a0, actor<BaseT1> const& a1);
+}}
+
+namespace boost
+{
+    template <typename Eval>
+    struct result_of<phoenix::actor<Eval>()>
+    {
+        typedef typename phoenix::actor<Eval>::nullary_result type;
+    };
+    
+    template <typename Eval>
+    struct result_of<phoenix::actor<Eval> const()>
+        : result_of<phoenix::actor<Eval>()>
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/argument.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/argument.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,93 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_ARGUMENT_HPP
+#define PHOENIX_CORE_ARGUMENT_HPP
+
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+#if !defined(PHOENIX_ARG_LIMIT)
+# define PHOENIX_ARG_LIMIT PHOENIX_LIMIT
+#endif
+
+#define PHOENIX_DECLARE_ARG(z, n, data)                                         \
+    actor<argument<n> > const                                                   \
+        BOOST_PP_CAT(arg, BOOST_PP_INC(n)) = argument<n>();                     \
+    actor<argument<n> > const                                                   \
+        BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument<n>();
+
+namespace boost { namespace phoenix
+{
+    namespace detail
+    {
+        template <typename Arg>
+        struct error_argument_not_found {};
+        inline void test_invalid_argument(int) {}
+    }
+
+    template <int N>
+    struct argument
+    {
+        typedef mpl::true_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename
+                fusion::result_of::at<typename Env::tie_type, mpl::int_<N> >::type
+            type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            typedef typename
+                mpl::if_<
+                    mpl::less<mpl::int_<N>, mpl::size<typename Env::args_type> >
+                  , int
+                  , detail::error_argument_not_found<argument<N> >
+                >::type
+            check_out_of_bounds;
+
+            detail::test_invalid_argument(check_out_of_bounds());
+            return fusion::at_c<N>(env.args());
+        }
+    };
+
+    namespace arg_names
+    {
+    //  Phoenix style names
+        actor<argument<0> > const arg1 = argument<0>();
+        actor<argument<1> > const arg2 = argument<1>();
+        actor<argument<2> > const arg3 = argument<2>();
+
+    //  BLL style names
+        actor<argument<0> > const _1 = argument<0>();
+        actor<argument<1> > const _2 = argument<1>();
+        actor<argument<2> > const _3 = argument<2>();
+
+    //  Bring in the rest or the Phoenix style arguments (arg4 .. argN+1)
+    //  and BLL style arguments (_4 .. _N+1), using PP
+        BOOST_PP_REPEAT_FROM_TO(
+            3, PHOENIX_ARG_LIMIT, PHOENIX_DECLARE_ARG, _)
+    }
+}}
+
+#undef PHOENIX_DECLARE_ARG
+#endif
Added: trunk/boost/spirit/home/phoenix/core/as_actor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/as_actor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,62 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_AS_ACTOR_HPP
+#define PHOENIX_CORE_AS_ACTOR_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename T>
+    struct as_actor_base; // defined in value.hpp
+
+    template <typename Base>
+    struct as_actor_base<actor<Base> >
+    {
+        typedef Base type;
+
+        static Base const&
+        convert(actor<Base> const& x)
+        {
+            return x;
+        }
+    };
+
+    template <>
+    struct as_actor_base<fusion::void_>
+    {
+        typedef fusion::void_ type;
+        struct error_attempting_to_convert_void_type_to_an_actor {};
+
+        static void
+        convert(error_attempting_to_convert_void_type_to_an_actor);
+    };
+
+    template <>
+    struct as_actor_base<void>
+    {
+        typedef void type;
+        struct error_attempting_to_convert_void_type_to_an_actor {};
+
+        static void
+        convert(error_attempting_to_convert_void_type_to_an_actor);
+    };
+
+    template <typename T>
+    struct as_actor
+    {
+        typedef actor<typename as_actor_base<T>::type> type;
+
+        static type
+        convert(T const& x)
+        {
+            return as_actor_base<T>::convert(x);
+        }
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/basic_environment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/basic_environment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_BASIC_ENVIRONMENT_HPP
+#define PHOENIX_CORE_BASIC_ENVIRONMENT_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+
+#if !defined(PHOENIX_ARG_LIMIT)
+# define PHOENIX_ARG_LIMIT PHOENIX_LIMIT
+#endif
+
+#include <boost/mpl/remove.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/mpl.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <
+        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+            PHOENIX_ARG_LIMIT, typename T, fusion::void_)>
+    class basic_environment
+    {
+        typedef
+            mpl::BOOST_PP_CAT(vector, PHOENIX_ARG_LIMIT)<
+                BOOST_PP_ENUM_PARAMS(PHOENIX_ARG_LIMIT, T)>
+        args_with_void_type;
+
+    public:
+
+        // args_type: the list of types in an mpl::sequence
+        typedef typename 
+            mpl::remove<args_with_void_type, fusion::void_>::type 
+        args_type;
+        
+        // tie_type: a fusion::tuple of references
+        typedef typename
+            fusion::result_of::as_vector<
+                typename mpl::transform<
+                    args_type, boost::add_reference<mpl::_1> 
+                >::type
+            >::type
+        tie_type;
+
+        basic_environment()
+            : args_() {}
+
+        template <typename U0>
+        explicit basic_environment(U0& _0)
+            : args_(_0) {}
+
+        template <typename U0, typename U1>
+        basic_environment(U0& _0, U1& _1)
+            : args_(_0, _1) {}
+
+        //  Bring in the rest of the constructors
+        #include <boost/spirit/home/phoenix/core/detail/basic_environment.hpp>
+
+        tie_type const& 
+        args() const
+        {
+            return args_;
+        }
+
+        tie_type& 
+        args()
+        {
+            return args_;
+        }
+
+    private:
+
+        tie_type args_;
+    };
+}}
+
+#endif
+
Added: trunk/boost/spirit/home/phoenix/core/compose.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/compose.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,118 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_COMPOSE_HPP
+#define PHOENIX_CORE_COMPOSE_HPP
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/value.hpp>
+#include <boost/spirit/home/phoenix/core/as_actor.hpp>
+
+#define PHOENIX_AS_ACTOR(z, n, data)                                            \
+    typename mpl::eval_if<                                                      \
+        is_same<BOOST_PP_CAT(T, n), fusion::void_>                              \
+      , mpl::identity<fusion::void_>                                            \
+      , as_actor_base<BOOST_PP_CAT(T, n)>                                       \
+    >::type
+
+namespace boost { namespace phoenix
+{
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  as_composite<EvalPolicy, T0,... TN> metafunction
+//
+//      Create a composite given an EvalPolicy and types T0..TN.
+//      The types are converted to an actor through the as_actor
+//      metafunction (see as_actor.hpp).
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <
+        typename EvalPolicy
+      , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+            PHOENIX_COMPOSITE_LIMIT, typename T, fusion::void_)>
+    struct as_composite
+    {
+        typedef composite<
+            EvalPolicy
+          , fusion::vector<
+                BOOST_PP_ENUM(PHOENIX_COMPOSITE_LIMIT, PHOENIX_AS_ACTOR, _)>
+        >
+        type;
+    };
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  compose functions
+//
+//      Usage:
+//
+//          compose<EvalPolicy>(_0, _1,... _N)
+//
+//      Returns a composite given an EvalPolicy and arguments _0.._N. 
+//      The arguments are converted to an actor through the as_actor
+//      metafunction (see as_actor.hpp).
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <typename EvalPolicy>
+    inline actor<typename as_composite<EvalPolicy>::type>
+    compose()
+    {
+        return actor<typename as_composite<EvalPolicy>::type>();
+    }
+
+    template <typename EvalPolicy, typename T0>
+    inline actor<typename as_composite<EvalPolicy, T0>::type>
+    compose(T0 const& _0)
+    {
+        return actor<typename as_composite<EvalPolicy, T0>::type>(
+            as_actor<T0>::convert(_0)
+        );
+    }
+
+    template <typename EvalPolicy, typename T0, typename T1>
+    inline actor<typename as_composite<EvalPolicy, T0, T1>::type>
+    compose(T0 const& _0, T1 const& _1)
+    {
+        return actor<typename as_composite<EvalPolicy, T0, T1>::type>(
+            as_actor<T0>::convert(_0)
+          , as_actor<T1>::convert(_1)
+        );
+    }
+
+    //  Bring in the the rest of the compose overloads
+    #include <boost/spirit/home/phoenix/core/detail/compose.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  re_curry<EvalPolicy, T0,...TN>
+//
+//      returns the result of re currying T0..TN using EvalPolicy.
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <
+        typename EvalPolicy
+      , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+            PHOENIX_COMPOSITE_LIMIT, typename T, fusion::void_)>
+    struct re_curry
+    {
+        typedef actor<
+            typename as_composite<
+                EvalPolicy
+              , BOOST_PP_ENUM_PARAMS(PHOENIX_COMPOSITE_LIMIT, T)>::type
+            >
+        type;
+    };
+}}
+
+#undef PHOENIX_AS_ACTOR
+#endif
Added: trunk/boost/spirit/home/phoenix/core/composite.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/composite.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,100 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_COMPOSITE_HPP
+#define PHOENIX_CORE_COMPOSITE_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/is_actor.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/or.hpp>
+
+#if !defined(PHOENIX_COMPOSITE_LIMIT)
+# define PHOENIX_COMPOSITE_LIMIT PHOENIX_LIMIT
+#endif
+
+namespace boost { namespace phoenix
+{
+    namespace detail
+    {
+        template <int N>
+        struct composite_eval;
+        
+        struct compute_no_nullary
+        {
+            template <typename State, typename T>
+            struct apply
+            {
+                typedef typename 
+                    mpl::or_<typename T::no_nullary, State>::type
+                type;
+            };
+        };
+    }
+
+    template <typename EvalPolicy, typename EvalTuple>
+    struct composite : EvalTuple
+    {
+        typedef EvalTuple base_type;
+        typedef composite<EvalPolicy, EvalTuple> self_type;
+        typedef EvalPolicy eval_policy_type;
+        
+        typedef typename
+            mpl::fold<
+                EvalTuple
+              , mpl::false_
+              , detail::compute_no_nullary
+            >::type
+        no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef
+                typename detail::composite_eval<
+                    fusion::result_of::size<base_type>::value>::
+                template result<self_type, Env>::type
+            type;
+        };
+
+        composite()
+            : base_type() {}
+
+        composite(base_type const& base)
+            : base_type(base) {}
+
+        template <typename U0>
+        composite(U0& _0)
+            : base_type(_0) {}
+
+        template <typename U0, typename U1>
+        composite(U0& _0, U1& _1)
+            : base_type(_0, _1) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            typedef typename result<Env>::type return_type;
+            return detail::
+                composite_eval<fusion::result_of::size<base_type>::value>::template
+                    call<return_type>(*this, env);
+        }
+
+        //  Bring in the rest of the constructors
+        #include <boost/spirit/home/phoenix/core/detail/composite.hpp>
+    };
+
+    //  Bring in the detail::composite_eval<0..N> definitions
+    #include <boost/spirit/home/phoenix/core/detail/composite_eval.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/detail/actor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/actor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,65 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_CORE_DETAIL_ACTOR_HPP
+#define PHOENIX_CORE_DETAIL_ACTOR_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_ACTOR_LIMIT,                                                \
+    "boost/spirit/home/phoenix/core/detail/actor.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+    actor(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _))
+        : Eval(BOOST_PP_ENUM_PARAMS(N, _)) {}
+
+    template <typename F, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    struct result<F(BOOST_PP_ENUM_PARAMS(N, A))>
+      : eval_result<
+            eval_type
+          , basic_environment<
+                BOOST_PP_ENUM_BINARY_PARAMS(
+                    N
+                  , typename remove_reference<typename add_const<A
+                  , >::type>::type BOOST_PP_INTERCEPT
+                )
+            >
+        >
+    {};
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+    typename result<
+        actor(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & BOOST_PP_INTERCEPT))
+    >::type
+    operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & _)) const
+    {
+        return eval_type::eval(
+            basic_environment<BOOST_PP_ENUM_PARAMS(N, T)>(
+                BOOST_PP_ENUM_PARAMS(N, _))
+        );
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/detail/basic_environment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/basic_environment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,38 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_CORE_DETAIL_BASIC_ENVIRONMENT_HPP
+#define PHOENIX_CORE_DETAIL_BASIC_ENVIRONMENT_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_ARG_LIMIT,                                                  \
+    "boost/spirit/home/phoenix/core/detail/basic_environment.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename U)>
+    basic_environment(BOOST_PP_ENUM_BINARY_PARAMS(N, U, & _))
+        : args_(BOOST_PP_ENUM_PARAMS(N, _)) {}
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/detail/compose.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/compose.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,47 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_CORE_DETAIL_COMPOSE_DETAIL_HPP
+#define PHOENIX_CORE_DETAIL_COMPOSE_DETAIL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+
+#define PHOENIX_AS_ACTOR_CONVERT(z, n, data)                                    \
+    as_actor<BOOST_PP_CAT(T, n)>::convert(BOOST_PP_CAT(_, n))
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/core/detail/compose.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_AS_ACTOR_CONVERT
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename EvalPolicy, BOOST_PP_ENUM_PARAMS(N, typename T)>
+    inline actor<
+        typename as_composite<EvalPolicy, BOOST_PP_ENUM_PARAMS(N, T)>::type>
+    compose(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _))
+    {
+        return actor<
+            typename as_composite<EvalPolicy, BOOST_PP_ENUM_PARAMS(N, T)>::type>(
+                BOOST_PP_ENUM(N, PHOENIX_AS_ACTOR_CONVERT, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/detail/composite.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/composite.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,36 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_CORE_DETAIL_COMPOSITE_HPP
+#define PHOENIX_CORE_DETAIL_COMPOSITE_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/core/detail/composite.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename U)>
+    composite(BOOST_PP_ENUM_BINARY_PARAMS(N, U, & _))
+        : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {}
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/detail/composite_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/composite_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,106 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_CORE_DETAIL_COMPOSITE_EVAL_HPP
+#define PHOENIX_CORE_DETAIL_COMPOSITE_EVAL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+    namespace detail
+    {
+        template <int N>
+        struct composite_eval;
+
+        template <>
+        struct composite_eval<0>
+        {
+            template <typename Composite, typename Env>
+            struct result
+            {
+                typedef typename Composite::eval_policy_type::
+                    template result<Env>::type
+                type;
+            };
+
+            template <typename RT, typename Composite, typename Env>
+            static RT
+            call(Composite const& composite, Env const& env)
+            {
+                typedef typename Composite::eval_policy_type eval_policy_type;
+                return eval_policy_type::template eval<RT>(env);
+            }
+        };
+
+        template <typename Actor, typename Env>
+        struct eval_is_actor
+            : is_actor<typename Actor::template result<Env>::type> {};
+
+        template <typename Actor, typename Env>
+        struct eval_is_void
+            : is_same<typename Actor::template result<Env>::type, fusion::void_> {};
+    }
+
+#define PHOENIX_GET_ACTOR_TYPE(z, n, data)                                      \
+    typedef                                                                     \
+        typename fusion::result_of::value_at_c<Composite, n>::type              \
+    BOOST_PP_CAT(actor, n);
+
+#define PHOENIX_GET_ACTOR(z, n, data)                                           \
+    fusion::at_c<n>(composite)
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (1, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/core/detail/composite_eval.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_GET_ACTOR
+#undef PHOENIX_GET_ACTOR_TYPE
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    namespace detail
+    {
+        template <>
+        struct composite_eval<N>
+        {
+            template <typename Composite, typename Env>
+            struct result
+            {
+                BOOST_PP_REPEAT(N, PHOENIX_GET_ACTOR_TYPE, _)
+
+                typedef typename
+                    Composite::eval_policy_type::template result<
+                        Env, BOOST_PP_ENUM_PARAMS(N, actor)
+                    >::type
+                type;
+            };
+
+            template <typename RT, typename Composite, typename Env>
+            static RT
+            call(Composite const& composite, Env const& env)
+            {
+                typedef typename Composite::eval_policy_type eval_policy_type;
+                return eval_policy_type::template eval<RT>(
+                    env, BOOST_PP_ENUM(N, PHOENIX_GET_ACTOR, _));
+            }
+        };
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/detail/composite_info.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/composite_info.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,40 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_DETAIL_COMPOSITE_INFO_HPP
+#define PHOENIX_CORE_DETAIL_COMPOSITE_INFO_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/spirit/home/fusion/algorithm/fold.hpp>
+
+namespace boost { namespace phoenix { namespace detail
+{
+    struct max_nesting
+    {
+        template <typename T, typename State>
+        struct result :
+            mpl::if_<
+                mpl::greater<typename T::nesting, State>
+              , typename T::nesting
+              , State
+            >
+        {};
+    };
+
+    template <typename ActorTuple>
+    struct compute_nesting
+    {
+        typedef typename
+            fusion::meta::fold<ActorTuple, mpl::int_<0>, max_nesting>::type
+        type;
+    };
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/phoenix/core/detail/function_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/detail/function_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,134 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_PP_IS_ITERATING)
+#if !defined(PHOENIX_CORE_DETAIL_FUNCTION_EVAL_HPP)
+#define PHOENIX_CORE_DETAIL_FUNCTION_EVAL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/enum.hpp>
+#include <boost/preprocessor/repeat.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+// we assume that mpl::vectorN, where N = PHOENIX_COMPOSITE_LIMIT
+// is included already.
+
+namespace boost { namespace phoenix { namespace detail
+{
+    template <int N>
+    struct function_eval;
+
+    template <>
+    struct function_eval<0>
+    {
+        template <typename Env, typename F>
+        struct result
+        {
+            typedef typename F::template result<Env>::type function;
+            typedef typename function::result_type type;
+        };
+
+        template <typename RT, typename Env, typename F>
+        static RT
+        eval(Env const& env, F const& f)
+        {
+            return f.eval(env)();
+        }
+    };
+
+    template <typename T>
+    T& help_rvalue_deduction(T& x)
+    {
+        return x;
+    }
+
+    template <typename T>
+    T const& help_rvalue_deduction(T const& x)
+    {
+        return x;
+    }
+
+// When we call f(_0, _1...) we remove the reference when deducing f's
+// return type. $$$ Explain why $$$
+
+#define PHOENIX_GET_ARG(z, n, data)                                             \
+    typedef typename                                                            \
+        remove_reference<                                                       \
+            typename BOOST_PP_CAT(A, n)::template result<Env>::type             \
+        >::type                                                                 \
+    BOOST_PP_CAT(a, n);
+
+#define PHOENIX_EVAL_ARG(z, n, data)                                            \
+    help_rvalue_deduction(BOOST_PP_CAT(_, n).eval(env))
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (1, BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT),                              \
+    "boost/spirit/home/phoenix/core/detail/function_eval.hpp"))
+#include BOOST_PP_ITERATE()
+
+}}} // namespace boost::phoenix::detail
+
+#undef PHOENIX_GET_ARG
+#undef PHOENIX_EVAL_ARG
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <>
+    struct function_eval<N>
+    {
+        template <typename Env, typename F
+          , BOOST_PP_ENUM_PARAMS(N, typename A)>
+        struct result
+        {
+            typedef typename F::template result<Env>::type function;
+            BOOST_PP_REPEAT(N, PHOENIX_GET_ARG, _)
+
+            typedef BOOST_PP_CAT(mpl::vector, N)
+                <BOOST_PP_ENUM_PARAMS(N, a)>
+            args;
+
+            typedef typename
+                function::template result<BOOST_PP_ENUM_PARAMS(N, a)>
+            function_apply;
+
+            typedef typename
+                mpl::eval_if<
+                    is_same<
+                        typename mpl::find<args, fusion::void_>::type
+                      , typename mpl::end<args>::type>
+                  , function_apply
+                  , mpl::identity<fusion::void_>
+                >::type
+            type;
+        };
+
+        template <typename RT, typename Env, typename F
+          , BOOST_PP_ENUM_PARAMS(N, typename A)>
+        static RT
+        eval(Env const& env, F const& f
+          , BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _))
+        {
+            return f.eval(env)(BOOST_PP_ENUM(N, PHOENIX_EVAL_ARG, _));
+        }
+    };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/core/is_actor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/is_actor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,29 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_IS_ACTOR_HPP
+#define PHOENIX_CORE_IS_ACTOR_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix
+{
+///////////////////////////////////////////////////////////////////////////////
+//
+//  is_actor<T>
+//
+//      Tests if T is an actor. Evaluates to mpl::true_ or mpl::false_
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct is_actor : mpl::false_ {};
+
+    template <typename Base>
+    struct is_actor<actor<Base> > : mpl::true_ {};
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/limits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/limits.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,34 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_LIMITS_HPP
+#define PHOENIX_CORE_LIMITS_HPP
+
+#if !defined(PHOENIX_LIMIT)
+# define PHOENIX_LIMIT 10
+#endif
+
+#if !defined(PHOENIX_ACTOR_LIMIT)
+# define PHOENIX_ACTOR_LIMIT PHOENIX_LIMIT
+#elif (PHOENIX_ACTOR_LIMIT > PHOENIX_LIMIT)
+# error "PHOENIX_ACTOR_LIMIT is set too high"
+#endif
+
+#if !defined(FUSION_MAX_TUPLE_SIZE)
+# define FUSION_MAX_TUPLE_SIZE PHOENIX_LIMIT
+#elif (FUSION_MAX_TUPLE_SIZE < PHOENIX_LIMIT)
+# error "FUSION_MAX_TUPLE_SIZE is set too low"
+#endif
+
+// this include will bring in mpl::vectorN and 
+// fusion::tupleN where N is PHOENIX_ACTOR_LIMIT
+#include <boost/fusion/include/vector.hpp>
+
+// for some reason, this must be included now to make
+// detail/type_deduction.hpp compile. $$$ TODO: Investigate further $$$
+#include <boost/mpl/vector/vector20.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/nothing.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/nothing.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_NOTHING_HPP
+#define PHOENIX_CORE_NOTHING_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix
+{
+///////////////////////////////////////////////////////////////////////////////
+//
+//  null_actor
+//
+//      A actor that does nothing (a "bum", if you will :-).
+//
+///////////////////////////////////////////////////////////////////////////////
+    struct null_actor 
+    {
+        typedef mpl::false_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename Env>
+        void
+        eval(Env const&) const
+        {
+        }
+    };
+
+    null_actor const nothing = null_actor();
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/reference.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/reference.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,76 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_REFERENCE_HPP
+#define PHOENIX_CORE_REFERENCE_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename T>
+    struct reference
+    {
+        // $$$ TODO: a better (user friendly) static assert
+        BOOST_STATIC_ASSERT(
+            mpl::not_<is_reference<T> >::value != 0);
+
+        typedef mpl::false_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef T& type;
+        };
+
+        reference(T& arg)
+            : ref(arg) {}
+
+        template <typename Env>
+        T& eval(Env const&) const
+        {
+            return ref;
+        }
+
+        T& ref;
+    };
+
+    template <typename T>
+    inline actor<reference<T> > const
+    ref(T& v)
+    {
+        return reference<T>(v);
+    }
+
+    template <typename T>
+    inline actor<reference<T const> > const
+    cref(T const& v)
+    {
+        return reference<T const>(v);
+    }
+
+    namespace detail
+    {
+        struct error_attempting_to_convert_an_actor_to_a_reference {};
+    }
+
+    template <typename Base>
+    void
+    ref(actor<Base> const& v
+        , detail::error_attempting_to_convert_an_actor_to_a_reference
+            = detail::error_attempting_to_convert_an_actor_to_a_reference());
+
+    template <typename Base>
+    void
+    cref(actor<Base> const& v
+        , detail::error_attempting_to_convert_an_actor_to_a_reference
+            = detail::error_attempting_to_convert_an_actor_to_a_reference());
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/core/value.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/core/value.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,155 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CORE_VALUE_HPP
+#define PHOENIX_CORE_VALUE_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/as_actor.hpp>
+#include <boost/static_assert.hpp>
+
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/is_function.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace meta
+    {
+        template<typename T>
+        struct const_ref
+            : add_reference<typename add_const<T>::type>
+        {};
+
+        template<typename T>
+        struct argument_type
+            : mpl::eval_if<
+            is_function<typename remove_pointer<T>::type>,
+            mpl::identity<T>,
+            const_ref<T> >
+        {
+            typedef T type;
+        };
+    }
+
+    template <typename T>
+    struct value 
+    {
+        BOOST_STATIC_ASSERT(
+            mpl::not_<is_reference<T> >::value != 0);
+
+        typedef mpl::false_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef T type;
+        };
+
+        value(T const& arg)
+            : val(arg) {}
+
+        template <typename Env>
+        T const&
+        eval(Env const&) const
+        {
+            return val;
+        }
+
+        T val;
+    };
+
+    template <typename Actor>
+    struct actor_value 
+    {
+        typedef typename Actor::no_nullary no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename 
+                remove_reference<
+                    typename eval_result<Actor, Env>::type
+                >::type
+            type;
+        };
+
+        actor_value(Actor const& actor)
+            : actor(actor) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return actor.eval(env);
+        }
+
+        Actor actor;
+    };
+
+    template <typename T>
+    inline typename as_actor<T>::type
+    val(T const& v)
+    {
+        return as_actor<T>::convert(v);
+    }
+
+    template <typename Derived>
+    inline actor<actor_value<Derived> >
+    val(actor<Derived> const& actor)
+    {
+        return actor_value<Derived>(actor);
+    }
+
+    template <typename T>
+    struct as_actor_base
+    {
+        typedef value<T> type;
+
+        static value<T>
+        convert(typename meta::argument_type<T>::type x)
+        {
+            return value<T>(x);
+        }
+    };
+
+    // 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>
+    struct as_actor_base<T&>
+    {
+        typedef value<T> type;
+
+        static value<T>
+        convert(T& x)
+        {
+            return value<T>(x);
+        }
+    };
+
+    template <typename T, int N>
+    struct as_actor_base<T[N]>
+    {
+        typedef value<T const*> type;
+
+        static value<T const*>
+        convert(T const x[N])
+        {
+            return value<T const*>(x);
+        }
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/detail/local_reference.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/detail/local_reference.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,44 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_DETAIL_LOCAL_REFERENCE_HPP
+#define PHOENIX_DETAIL_LOCAL_REFERENCE_HPP
+
+#include <boost/utility/addressof.hpp>
+
+namespace boost { namespace phoenix { namespace detail
+{
+    template <typename T>
+    struct local_reference
+    { 
+        typedef T type;
+    
+        explicit local_reference(T& t): t_(boost::addressof(t)) {}
+        operator T& () const { return *t_; }
+        local_reference& operator=(T const& x) { *t_ = x; return *this; }
+        local_reference const& operator=(T const& x) const { *t_ = x; return *this; }
+        T& get() const { return *t_; }
+        T* get_pointer() const { return t_; }
+    
+    private:
+    
+        T* t_;
+    };
+    
+    template <typename T>
+    struct unwrap_local_reference
+    {
+        typedef T type; // T should be a reference
+    };
+
+    template <typename T>
+    struct unwrap_local_reference<local_reference<T> >
+    {
+        typedef T type; // unwrap the reference; T is a value
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/detail/type_deduction.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/detail/type_deduction.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,480 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_DETAIL_TYPE_DEDUCTION_HPP
+#define PHOENIX_DETAIL_TYPE_DEDUCTION_HPP
+
+/*=============================================================================
+
+    Return Type Deduction
+    [JDG Sept. 15, 2003]
+
+    Before C++ adopts the typeof, there is currently no way to deduce the
+    result type of an expression such as x + y. This deficiency is a major
+    problem with template metaprogramming; for example, when writing
+    forwarding functions that attempt to capture the essence of an
+    expression inside a function. Consider the std::plus<T>:
+
+        template <typename T>
+        struct plus : public binary_function<T, T, T>
+        {
+            T operator()(T const& x, T const& y) const
+            {
+                return x + y;
+            }
+        };
+
+    What's wrong with this? Well, this functor does not accurately capture
+    the behavior of the plus operator. 1) It does not handle the case where
+    x and y are of different types (e.g. x is short and y is int). 2) It
+    assumes that the arguments and return type are the same (i.e. when
+    adding a short and an int, the return type ought to be an int). Due to
+    these shortcomings, std::plus<T>(x, y) is a poor substitute for x + y.
+
+    The case where x is short and y is int does not really expose the
+    problem. We can simply use std::plus<int> and be happy that the
+    operands x and y will simply be converted to an int. The problem
+    becomes evident when an operand is a user defined type such as bigint.
+    Here, the conversion to bigint is simply not acceptable. Even if the
+    unnecessary conversion is tolerable, in generic code, it is not always
+    possible to choose the right T type that can accomodate both x and y
+    operands.
+
+    To truly model the plus operator, what we need is a polymorphic functor
+    that can take arbitrary x and y operands. Here's a rough schematic:
+
+        struct plus
+        {
+            template <typename X, typename Y>
+            unspecified-type
+            operator()(X const& x, Y const& y) const
+            {
+                return x + y;
+            }
+        };
+
+    Now, we can handle the case where X and Y are arbitrary types. We've
+    solved the first problem. To solve the second problem, we need some
+    form of return type deduction mechanism. If we had the typeof, it would
+    be something like:
+
+        template <typename X, typename Y>
+        typeof(X() + Y())
+        operator()(X const& x, Y const& y) const
+        {
+            return x + y;
+        }
+
+    Without the typeof facility, it is only possible to wrap an expression
+    such as x + y in a function or functor if we are given a hint that
+    tells us what the actual result type of such an expression is. Such a
+    hint can be in the form of a metaprogram, that, given the types of the
+    arguments, will return the result type. Example:
+
+        template <typename X, typename Y>
+        struct result_of_plus
+        {
+            typedef unspecified-type type;
+        };
+
+    Given a result_of_plus metaprogram, we can complete our polymorphic
+    plus functor:
+
+        struct plus
+        {
+            template <typename X, typename Y>
+            typename result_of_plus<X, Y>::type
+            operator()(X const& x, Y const& y) const
+            {
+                return x + y;
+            }
+        };
+
+    The process is not automatic. We have to specialize the metaprogram for
+    specific argument types. Examples:
+
+        template <>
+        struct result_of_plus<short, int>
+        {
+            typedef int type;
+        };
+
+        template <typename T>
+        struct result_of_plus<std::complex<T>, std::complex<T> >
+        {
+            typedef std::complex<T> type;
+        };
+
+    To make it easier for the user, specializations are provided for common
+    types such as primitive c++ types (e.g. int, char, double, etc.), and
+    standard types (e.g. std::complex, iostream, std containers and
+    iterators).
+
+    To further improve the ease of use, for user defined classes, we can
+    supply a few more basic specializations through metaprogramming using
+    heuristics based on canonical operator rules (Such heuristics can be
+    found in the LL and Phoenix, for example). For example, it is rather
+    common that the result of x += y is X& or the result of x || y is a
+    bool. The client is out of luck if her classes do not follow the
+    canonical rules. She'll then have to supply her own specialization.
+
+    The type deduction mechanism demostrated below approaches the problem
+    not through specialization and heuristics, but through a limited form
+    of typeof mechanism. The code does not use heuristics, hence, no
+    guessing games. The code takes advantage of the fact that, in general,
+    the result type of an expression is related to one its arguments' type.
+    For example, x + y, where x has type int and y has type double, has the
+    result type double (the second operand type). Another example, x[y]
+    where x is a vector<T> and y is a std::size_t, has the result type
+    vector<T>::reference (the vector<T>'s reference type type).
+
+    The limited form of type deduction presented can detect common
+    relations if the result of a binary or unary operation, given arguments
+    x and y with types X and Y (respectively), is X, Y, X&, Y&, X*, Y*, X
+    const*, Y const*, bool, int, unsigned, double, container and iterator
+    elements (e.g the T, where X is: T[N], T*, vector<T>, map<T>,
+    vector<T>::iterator). More arguments/return type relationships can be
+    established if needed.
+
+    A set of overloaded test(T) functions capture these argument related
+    types. Each test(T) function returns a distinct type that can be used
+    to determine the exact type of an expression.
+
+    Consider:
+
+        template <typename X, typename Y>
+        x_value_type
+        test(X const&);
+
+        template <typename X, typename Y>
+        y_value_type
+        test(Y const&);
+
+    Given an expression x + y, where x is int and y is double, the call to:
+
+        test<int, double>(x + y)
+
+    will return a y_value_type.
+
+    Now, if we rig x_value_type and y_value_type such that both have unique
+    sizes, we can use sizeof(test<X, Y>(x + y)) to determine if the result
+    type is either X or Y.
+
+    For example, if:
+
+        sizeof(test<X, Y>(x + y)) == sizeof(y_value_type)
+
+    then, we know for sure that the result of x + y has type Y.
+
+    The same basic scheme can be used to detect more argument-dependent
+    return types where the sizeof the test(T) return type is used to index
+    through a boost::mpl vector which holds each of the corresponding
+    result types.
+
+==============================================================================*/
+#include <boost/mpl/vector/vector20.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/spirit/home/phoenix/detail/local_reference.hpp>
+
+namespace boost 
+{
+    struct error_cant_deduce_type {};
+}
+    
+namespace boost { namespace type_deduction_detail
+{
+    typedef char(&bool_value_type)[1];
+    typedef char(&int_value_type)[2];
+    typedef char(&uint_value_type)[3];
+    typedef char(&double_value_type)[4];
+
+    typedef char(&bool_reference_type)[5];
+    typedef char(&int_reference_type)[6];
+    typedef char(&uint_reference_type)[7];
+    typedef char(&double_reference_type)[8];
+
+    typedef char(&x_value_type)[9];
+    typedef char(&x_reference_type)[10];
+    typedef char(&x_const_pointer_type)[11];
+    typedef char(&x_pointer_type)[12];
+
+    typedef char(&y_value_type)[13];
+    typedef char(&y_reference_type)[14];
+    typedef char(&y_const_pointer_type)[15];
+    typedef char(&y_pointer_type)[16];
+
+    typedef char(&container_reference_type)[17];
+    typedef char(&container_const_reference_type)[18];
+    typedef char(&container_mapped_type)[19];
+
+    typedef char(&cant_deduce_type)[20];
+
+    template <typename T, typename Plain = typename remove_cv<T>::type>
+    struct is_basic
+        : mpl::or_<
+            is_same<Plain, bool>
+          , is_same<Plain, int>
+          , is_same<Plain, unsigned>
+          , is_same<Plain, double>
+        > {};
+
+    template <typename C>
+    struct reference_type
+    {
+        typedef typename C::reference type;
+    };
+
+    template <typename T, std::size_t N>
+    struct reference_type<T[N]>
+    {
+        typedef T& type;
+    };
+
+    template <typename T>
+    struct reference_type<T*>
+    {
+        typedef T& type;
+    };
+
+    template <typename C>
+    struct const_reference_type
+    {
+        typedef typename C::const_reference type;
+    };
+
+    template <typename C>
+    struct mapped_type
+    {
+        typedef typename C::mapped_type type;
+    };
+
+    struct asymmetric;
+
+    template <typename X, typename Y>
+    cant_deduce_type
+    test(...); // The black hole !!!
+
+    template <typename X, typename Y>
+    bool_value_type
+    test(bool const&);
+
+    template <typename X, typename Y>
+    int_value_type
+    test(int const&);
+
+    template <typename X, typename Y>
+    uint_value_type
+    test(unsigned const&);
+
+    template <typename X, typename Y>
+    double_value_type
+    test(double const&);
+
+    template <typename X, typename Y>
+    bool_reference_type
+    test(bool&);
+
+    template <typename X, typename Y>
+    int_reference_type
+    test(int&);
+
+    template <typename X, typename Y>
+    uint_reference_type
+    test(unsigned&);
+
+    template <typename X, typename Y>
+    double_reference_type
+    test(double&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<is_basic<X>, is_const<X> >
+      , x_value_type
+    >::type
+    test(X const&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        is_basic<X>
+      , x_reference_type
+    >::type
+    test(X&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_basic<X>
+          , is_const<X>
+        >
+      , x_const_pointer_type
+    >::type
+    test(X const*);
+
+    template <typename X, typename Y>
+    x_pointer_type
+    test(X*);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_basic<Y>
+          , is_same<Y, asymmetric>
+          , is_const<Y>
+          , is_same<X, Y>
+        >
+      , y_value_type
+    >::type
+    test(Y const&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_basic<Y>
+          , is_same<Y, asymmetric>
+          , is_same<X, Y>
+        >
+      , y_reference_type
+    >::type
+    test(Y&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_same<Y, asymmetric>
+          , is_const<Y>
+          , is_same<X, Y>
+        >
+      , y_const_pointer_type
+    >::type
+    test(Y const*);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_same<Y, asymmetric>
+          , is_same<X, Y>
+        >
+      , y_pointer_type
+    >::type
+    test(Y*);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        is_basic<typename X::value_type>
+      , container_reference_type
+    >::type
+    test(typename X::reference);
+
+    template <typename X, typename Y, typename Z>
+    typename enable_if<
+        mpl::and_<
+            mpl::or_<is_array<X>, is_pointer<X> >
+          , mpl::not_<is_basic<Z> >
+          , mpl::not_<is_same<X, Z> >
+        >
+      , container_reference_type
+    >::type
+    test(Z&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        is_basic<typename X::value_type>
+      , container_const_reference_type
+    >::type
+    test(typename X::const_reference);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        is_basic<typename X::mapped_type>
+      , container_mapped_type
+    >::type
+    test(typename X::mapped_type);
+
+    template <typename X, typename Y>
+    struct base_result_of
+    {
+        typedef typename phoenix::detail::unwrap_local_reference<X>::type x_type_;
+        typedef typename phoenix::detail::unwrap_local_reference<Y>::type y_type_;
+        typedef typename remove_reference<x_type_>::type x_type;
+        typedef typename remove_reference<y_type_>::type y_type;
+
+        typedef mpl::vector20<
+            mpl::identity<bool>
+          , mpl::identity<int>
+          , mpl::identity<unsigned>
+          , mpl::identity<double>
+          , mpl::identity<bool&>
+          , mpl::identity<int&>
+          , mpl::identity<unsigned&>
+          , mpl::identity<double&>
+          , mpl::identity<x_type>
+          , mpl::identity<x_type&>
+          , mpl::identity<x_type const*>
+          , mpl::identity<x_type*>
+          , mpl::identity<y_type>
+          , mpl::identity<y_type&>
+          , mpl::identity<y_type const*>
+          , mpl::identity<y_type*>
+          , reference_type<x_type>
+          , const_reference_type<x_type>
+          , mapped_type<x_type>
+          , mpl::identity<error_cant_deduce_type>
+        >
+        types;
+    };
+
+}} // namespace boost::type_deduction_detail
+
+#define BOOST_RESULT_OF_COMMON(expr, name, Y, SYMMETRY)                         \
+    struct name                                                                 \
+    {                                                                           \
+        typedef type_deduction_detail::base_result_of<X, Y> base_type;          \
+        static typename base_type::x_type x;                                    \
+        static typename base_type::y_type y;                                    \
+                                                                                \
+        BOOST_STATIC_CONSTANT(int,                                              \
+            size = sizeof(                                                      \
+                type_deduction_detail::test<                                    \
+                    typename base_type::x_type                                  \
+                  , SYMMETRY                                                    \
+                >(expr)                                                         \
+            ));                                                                 \
+                                                                                \
+        BOOST_STATIC_CONSTANT(int, index = (size / sizeof(char)) - 1);          \
+                                                                                \
+        typedef typename mpl::at_c<                                  	        \
+            typename base_type::types, index>::type id;                         \
+        typedef typename id::type type;                                         \
+    };
+
+#define BOOST_UNARY_RESULT_OF(expr, name)                                       \
+    template <typename X>                                                       \
+    BOOST_RESULT_OF_COMMON(expr, name,                                          \
+        type_deduction_detail::asymmetric, type_deduction_detail::asymmetric)
+
+#define BOOST_BINARY_RESULT_OF(expr, name)                                      \
+    template <typename X, typename Y>                                           \
+    BOOST_RESULT_OF_COMMON(expr, name, Y, typename base_type::y_type)
+
+#define BOOST_ASYMMETRIC_BINARY_RESULT_OF(expr, name)                           \
+    template <typename X, typename Y>                                           \
+    BOOST_RESULT_OF_COMMON(expr, name, Y, type_deduction_detail::asymmetric)
+
+#endif
Added: trunk/boost/spirit/home/phoenix/function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,13 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_FUNCTION_HPP
+#define PHOENIX_FUNCTION_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/function/function.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/function/detail/function_call.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/function/detail/function_call.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_FUNCTION_DETAIL_FUNCTION_CALL_HPP
+#define PHOENIX_FUNCTION_DETAIL_FUNCTION_CALL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT),                              \
+    "boost/spirit/home/phoenix/function/detail/function_call.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename A)>
+    actor<typename as_composite<detail::function_eval<N>, F
+      , BOOST_PP_ENUM_PARAMS(N, A)>::type>
+    operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _)) const
+    {
+        return compose<detail::function_eval<N> >(f, BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/function/function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/function/function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,48 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_FUNCTION_FUNCTION_HPP
+#define PHOENIX_FUNCTION_FUNCTION_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/detail/function_eval.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename F>
+    struct function
+    {
+        function() : f() {}
+        function(F const& f) : f(f) {}
+
+        actor<typename as_composite<detail::function_eval<0>, F>::type>
+        operator()() const
+        {
+            return compose<detail::function_eval<0> >(f);
+        }
+
+        template <typename A0>
+        actor<typename as_composite<detail::function_eval<1>, F, A0>::type>
+        operator()(A0 const& _0) const
+        {
+            return compose<detail::function_eval<1> >(f, _0);
+        }
+
+        template <typename A0, typename A1>
+        actor<typename as_composite<detail::function_eval<2>, F, A0, A1>::type>
+        operator()(A0 const& _0, A1 const& _1) const
+        {
+            return compose<detail::function_eval<2> >(f, _0, _1);
+        }
+
+        //  Bring in the rest of the function call operators
+        #include <boost/spirit/home/phoenix/function/detail/function_call.hpp>
+
+        F f;
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/fusion.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/fusion.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,12 @@
+/*=============================================================================
+    Copyright (c) 2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_FUSION_HPP
+#define PHOENIX_FUSION_HPP
+
+#include <boost/spirit/home/phoenix/fusion/at.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/fusion/at.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/fusion/at.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,49 @@
+/*=============================================================================
+    Copyright (c) 2005-2008 Hartmut Kaiser
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_SEQUENCE_AT_HPP
+#define PHOENIX_SEQUENCE_AT_HPP
+
+#include <boost/fusion/include/at.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <int N>
+    struct at_eval
+    {
+        template <typename Env, typename Tuple>
+        struct result
+        {
+            typedef typename Tuple::template result<Env>::type tuple;
+            typedef typename
+                fusion::result_of::at_c<
+                    typename remove_reference<tuple>::type, N
+                >::type
+            type;
+        };
+
+        template <typename RT, typename Env, typename Tuple>
+        static RT
+        eval(Env const& env, Tuple const& t)
+        {
+            return fusion::at_c<N>(t.eval(env));
+        }
+    };
+
+    template <int N, typename Tuple>
+    inline actor<typename as_composite<at_eval<N>, Tuple>::type>
+    at_c(Tuple const& tup)
+    {
+        return compose<at_eval<N> >(tup);
+    }
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,19 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_HPP
+#define PHOENIX_OBJECT_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/object/new.hpp>
+#include <boost/spirit/home/phoenix/object/construct.hpp>
+#include <boost/spirit/home/phoenix/object/delete.hpp>
+#include <boost/spirit/home/phoenix/object/static_cast.hpp>
+#include <boost/spirit/home/phoenix/object/const_cast.hpp>
+#include <boost/spirit/home/phoenix/object/dynamic_cast.hpp>
+#include <boost/spirit/home/phoenix/object/reinterpret_cast.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/const_cast.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/const_cast.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_CONST_CAST_HPP
+#define PHOENIX_OBJECT_CONST_CAST_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace impl
+    {
+        template <typename T>
+        struct const_cast_eval
+        {
+            template <typename Env, typename U>
+            struct result
+            {
+                typedef T type;
+            };
+
+            template <typename RT, typename Env, typename U>
+            static RT
+            eval(Env const& env, U& obj)
+            {
+                return const_cast<RT>(obj.eval(env));
+            }
+        };
+    }
+
+    template <typename T, typename U>
+    inline actor<typename as_composite<impl::const_cast_eval<T>, U>::type>
+    const_cast_(U const& obj)
+    {
+        return compose<impl::const_cast_eval<T> >(obj);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/construct.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/construct.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,80 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_CONSTRUCT_HPP
+#define PHOENIX_OBJECT_CONSTRUCT_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace detail
+    {
+        template <typename T>
+        struct construct_eval
+        {
+            template <typename Env,
+                BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+                    PHOENIX_COMPOSITE_LIMIT, typename T, fusion::void_)>
+            struct result
+            {
+                typedef T type;
+            };
+
+            template <typename RT, typename Env>
+            static RT
+            eval(Env const& env)
+            {
+                return RT();
+            }
+
+            template <typename RT, typename Env, typename A0>
+            static RT
+            eval(Env const& env, A0& _0)
+            {
+                return RT(_0.eval(env));
+            }
+
+            template <typename RT
+                , typename Env, typename A0, typename A1>
+            static RT
+            eval(Env const& env, A0& _0, A1& _1)
+            {
+                return RT(_0.eval(env), _1.eval(env));
+            }
+
+            //  Bring in the rest of the evals
+            #include <boost/spirit/home/phoenix/object/detail/construct_eval.hpp>
+        };
+    }
+
+    template <typename T>
+    inline actor<typename as_composite<detail::construct_eval<T> >::type>
+    construct()
+    {
+        return compose<detail::construct_eval<T> >();
+    }
+
+    template <typename T, typename A0>
+    inline actor<typename as_composite<detail::construct_eval<T>, A0>::type>
+    construct(A0 const& _0)
+    {
+        return compose<detail::construct_eval<T> >(_0);
+    }
+
+    template <typename T, typename A0, typename A1>
+    inline actor<typename as_composite<detail::construct_eval<T>, A0, A1>::type>
+    construct(A0 const& _0, A1 const& _1)
+    {
+        return compose<detail::construct_eval<T> >(_0, _1);
+    }
+
+    //  Bring in the rest of the new_ functions
+    #include <boost/spirit/home/phoenix/object/detail/construct.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/delete.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/delete.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,41 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_DELETE_HPP
+#define PHOENIX_OBJECT_DELETE_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace impl
+    {
+        struct delete_eval
+        {
+            template <typename Env, typename P>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename Args, typename Env, typename P>
+            static void
+            eval(Env const& env, P& p)
+            {
+                delete p.eval(env);
+            }
+        };
+    }
+
+    template <typename P>
+    inline actor<typename as_composite<impl::delete_eval, P>::type>
+    delete_(P const& p)
+    {
+        return compose<impl::delete_eval>(p);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/detail/construct.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/detail/construct.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OBJECT_DETAIL_CONSTRUCT_HPP
+#define PHOENIX_OBJECT_DETAIL_CONSTRUCT_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/object/detail/construct.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename T, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<typename as_composite<detail::construct_eval<T>
+        , BOOST_PP_ENUM_PARAMS(N, A)>::type>
+    construct(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        return compose<detail::construct_eval<T> >(BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/object/detail/construct_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/detail/construct_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,46 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OBJECT_DETAIL_CONSTRUCT_EVAL_HPP
+#define PHOENIX_OBJECT_DETAIL_CONSTRUCT_EVAL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define PHOENIX_EVAL_ARG(z, n, data)                                            \
+    BOOST_PP_CAT(_, n).eval(env)
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/object/detail/construct_eval.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_EVAL_ARG
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename RT, typename Env, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    static RT
+    eval(Env const& env, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _))
+    {
+        return RT(BOOST_PP_ENUM(N, PHOENIX_EVAL_ARG, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/object/detail/new.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/detail/new.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OBJECT_DETAIL_NEW_HPP
+#define PHOENIX_OBJECT_DETAIL_NEW_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/object/detail/new.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename T, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    inline actor<typename as_composite<detail::new_eval<T>
+        , BOOST_PP_ENUM_PARAMS(N, A)>::type>
+    new_(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _))
+    {
+        return compose<detail::new_eval<T> >(BOOST_PP_ENUM_PARAMS(N, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/object/detail/new_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/detail/new_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,47 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OBJECT_DETAIL_NEW_EVAL_HPP
+#define PHOENIX_OBJECT_DETAIL_NEW_EVAL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define PHOENIX_EVAL_ARG(z, n, data)                                            \
+    BOOST_PP_CAT(_, n).eval(env)
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_COMPOSITE_LIMIT,                                            \
+    "boost/spirit/home/phoenix/object/detail/new_eval.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_EVAL_ARG
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <typename RT, typename Env, BOOST_PP_ENUM_PARAMS(N, typename A)>
+    static RT
+    eval(Env const& env, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & _))
+    {
+        return new T(BOOST_PP_ENUM(N, PHOENIX_EVAL_ARG, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/object/dynamic_cast.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/dynamic_cast.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_DYNAMIC_CAST_HPP
+#define PHOENIX_OBJECT_DYNAMIC_CAST_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace impl
+    {
+        template <typename T>
+        struct dynamic_cast_eval
+        {
+            template <typename Env, typename U>
+            struct result
+            {
+                typedef T type;
+            };
+
+            template <typename RT, typename Env, typename U>
+            static RT
+            eval(Env const& env, U& obj)
+            {
+                return dynamic_cast<RT>(obj.eval(env));
+            }
+        };
+    }
+
+    template <typename T, typename U>
+    inline actor<typename as_composite<impl::dynamic_cast_eval<T>, U>::type>
+    dynamic_cast_(U const& obj)
+    {
+        return compose<impl::dynamic_cast_eval<T> >(obj);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/new.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/new.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,80 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_NEW_HPP
+#define PHOENIX_OBJECT_NEW_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace detail
+    {
+        template <typename T>
+        struct new_eval
+        {
+            template <typename Env,
+                BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+                    PHOENIX_COMPOSITE_LIMIT, typename T, fusion::void_)>
+            struct result
+            {
+                typedef T* type;
+            };
+
+            template <typename RT, typename Env>
+            static RT
+            eval(Env const& env)
+            {
+                return new T;
+            }
+
+            template <typename RT, typename Env, typename A0>
+            static RT
+            eval(Env const& env, A0& _0)
+            {
+                return new T(_0.eval(env));
+            }
+
+            template <typename RT, typename Env
+              , typename A0, typename A1>
+            static RT
+            eval(Env const& env, A0& _0, A1& _1)
+            {
+                return new T(_0.eval(env), _1.eval(env));
+            }
+
+            //  Bring in the rest of the evals
+            #include <boost/spirit/home/phoenix/object/detail/new_eval.hpp>
+        };
+    }
+
+    template <typename T>
+    inline actor<typename as_composite<detail::new_eval<T> >::type>
+    new_()
+    {
+        return compose<detail::new_eval<T> >();
+    }
+
+    template <typename T, typename A0>
+    inline actor<typename as_composite<detail::new_eval<T>, A0>::type>
+    new_(A0 const& _0)
+    {
+        return compose<detail::new_eval<T> >(_0);
+    }
+
+    template <typename T, typename A0, typename A1>
+    inline actor<typename as_composite<detail::new_eval<T>, A0, A1>::type>
+    new_(A0 const& _0, A1 const& _1)
+    {
+        return compose<detail::new_eval<T> >(_0, _1);
+    }
+
+    //  Bring in the rest of the new_ functions
+    #include <boost/spirit/home/phoenix/object/detail/new.hpp>
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/reinterpret_cast.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/reinterpret_cast.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_REINTERPRET_CAST_HPP
+#define PHOENIX_OBJECT_REINTERPRET_CAST_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace impl
+    {
+        template <typename T>
+        struct reinterpret_cast_eval
+        {
+            template <typename Env, typename U>
+            struct result
+            {
+                typedef T type;
+            };
+
+            template <typename RT, typename Env, typename U>
+            static RT
+            eval(Env const& env, U& obj)
+            {
+                return reinterpret_cast<RT>(obj.eval(env));
+            }
+        };
+    }
+
+    template <typename T, typename U>
+    inline actor<typename as_composite<impl::reinterpret_cast_eval<T>, U>::type>
+    reinterpret_cast_(U const& obj)
+    {
+        return compose<impl::reinterpret_cast_eval<T> >(obj);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/object/static_cast.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/object/static_cast.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,42 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OBJECT_STATIC_CAST_HPP
+#define PHOENIX_OBJECT_STATIC_CAST_HPP
+
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    namespace impl
+    {
+        template <typename T>
+        struct static_cast_eval
+        {
+            template <typename Env, typename U>
+            struct result
+            {
+                typedef T type;
+            };
+
+            template <typename RT, typename Env, typename U>
+            static RT
+            eval(Env const& env, U& obj)
+            {
+                return static_cast<RT>(obj.eval(env));
+            }
+        };
+    }
+
+    template <typename T, typename U>
+    inline actor<typename as_composite<impl::static_cast_eval<T>, U>::type>
+    static_cast_(U const& obj)
+    {
+        return compose<impl::static_cast_eval<T> >(obj);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,20 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_HPP
+#define PHOENIX_OPERATOR_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/operator/arithmetic.hpp>
+#include <boost/spirit/home/phoenix/operator/bitwise.hpp>
+#include <boost/spirit/home/phoenix/operator/comparison.hpp>
+#include <boost/spirit/home/phoenix/operator/if_else.hpp>
+#include <boost/spirit/home/phoenix/operator/logical.hpp>
+#include <boost/spirit/home/phoenix/operator/self.hpp>
+#include <boost/spirit/home/phoenix/operator/io.hpp>
+#include <boost/spirit/home/phoenix/operator/member.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/arithmetic.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/arithmetic.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,115 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_ARITHMETIC_HPP
+#define PHOENIX_OPERATOR_ARITHMETIC_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_compose.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct negate_eval;
+    struct posit_eval;
+    struct pre_increment_eval;
+    struct pre_decrement_eval;
+    struct post_increment_eval;
+    struct post_decrement_eval;
+
+    struct plus_assign_eval;
+    struct minus_assign_eval;
+    struct multiplies_assign_eval;
+    struct divides_assign_eval;
+    struct modulus_assign_eval;
+
+    struct plus_eval;
+    struct minus_eval;
+    struct multiplies_eval;
+    struct divides_eval;
+    struct modulus_eval;
+
+    BOOST_UNARY_RESULT_OF(-x, result_of_negate)
+    BOOST_UNARY_RESULT_OF(+x, result_of_posit)
+    BOOST_UNARY_RESULT_OF(++x, result_of_pre_increment)
+    BOOST_UNARY_RESULT_OF(--x, result_of_pre_decrement)
+    BOOST_UNARY_RESULT_OF(x++, result_of_post_increment)
+    BOOST_UNARY_RESULT_OF(x--, result_of_post_decrement)
+
+    BOOST_BINARY_RESULT_OF(x += y, result_of_plus_assign)
+    BOOST_BINARY_RESULT_OF(x -= y, result_of_minus_assign)
+    BOOST_BINARY_RESULT_OF(x *= y, result_of_multiplies_assign)
+    BOOST_BINARY_RESULT_OF(x /= y, result_of_divides_assign)
+    BOOST_BINARY_RESULT_OF(x %= y, result_of_modulus_assign)
+
+    BOOST_BINARY_RESULT_OF(x + y, result_of_plus)
+    BOOST_BINARY_RESULT_OF(x - y, result_of_minus)
+    BOOST_BINARY_RESULT_OF(x * y, result_of_multiplies)
+    BOOST_BINARY_RESULT_OF(x / y, result_of_divides)
+    BOOST_BINARY_RESULT_OF(x % y, result_of_modulus)
+
+#define x a0.eval(env)
+#define y a1.eval(env)
+
+    PHOENIX_UNARY_EVAL(negate_eval, result_of_negate, -x)
+    PHOENIX_UNARY_EVAL(posit_eval, result_of_posit, +x)
+    PHOENIX_UNARY_EVAL(pre_increment_eval, result_of_pre_increment, ++x)
+    PHOENIX_UNARY_EVAL(pre_decrement_eval, result_of_pre_decrement, --x)
+    PHOENIX_UNARY_EVAL(post_increment_eval, result_of_post_increment, x++)
+    PHOENIX_UNARY_EVAL(post_decrement_eval, result_of_post_decrement, x--)
+
+    PHOENIX_BINARY_EVAL(plus_assign_eval, result_of_plus_assign, x += y)
+    PHOENIX_BINARY_EVAL(minus_assign_eval, result_of_minus_assign, x -= y)
+    PHOENIX_BINARY_EVAL(multiplies_assign_eval, result_of_multiplies_assign, x *= y)
+    PHOENIX_BINARY_EVAL(divides_assign_eval, result_of_divides_assign, x /= y)
+    PHOENIX_BINARY_EVAL(modulus_assign_eval, result_of_modulus_assign, x %= y)
+
+    PHOENIX_BINARY_EVAL(plus_eval, result_of_plus, x + y)
+    PHOENIX_BINARY_EVAL(minus_eval, result_of_minus, x - y)
+    PHOENIX_BINARY_EVAL(multiplies_eval, result_of_multiplies, x * y)
+    PHOENIX_BINARY_EVAL(divides_eval, result_of_divides, x / y)
+    PHOENIX_BINARY_EVAL(modulus_eval, result_of_modulus, x % y)
+
+    PHOENIX_UNARY_COMPOSE(negate_eval, -)
+    PHOENIX_UNARY_COMPOSE(posit_eval, +)
+    PHOENIX_UNARY_COMPOSE(pre_increment_eval, ++)
+    PHOENIX_UNARY_COMPOSE(pre_decrement_eval, --)
+
+    template <typename T0>
+    inline actor<typename as_composite<post_increment_eval, actor<T0> >::type>
+    operator++(actor<T0> const& a0, int) // special case
+    {
+        return compose<post_increment_eval>(a0);
+    }
+
+    template <typename T0>
+    inline actor<typename as_composite<post_decrement_eval, actor<T0> >::type>
+    operator--(actor<T0> const& a0, int) // special case
+    {
+        return compose<post_decrement_eval>(a0);
+    }
+
+    PHOENIX_BINARY_COMPOSE(plus_assign_eval, +=)
+    PHOENIX_BINARY_COMPOSE(minus_assign_eval, -=)
+    PHOENIX_BINARY_COMPOSE(multiplies_assign_eval, *=)
+    PHOENIX_BINARY_COMPOSE(divides_assign_eval, /=)
+    PHOENIX_BINARY_COMPOSE(modulus_assign_eval, %=)
+
+    PHOENIX_BINARY_COMPOSE(plus_eval, +)
+    PHOENIX_BINARY_COMPOSE(minus_eval, -)
+    PHOENIX_BINARY_COMPOSE(multiplies_eval, *)
+    PHOENIX_BINARY_COMPOSE(divides_eval, /)
+    PHOENIX_BINARY_COMPOSE(modulus_eval, %)
+
+#undef x
+#undef y
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/bitwise.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/bitwise.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,91 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_BITWISE_HPP
+#define PHOENIX_OPERATOR_BITWISE_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_compose.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_compose.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4800)
+#endif
+
+namespace boost { namespace phoenix
+{
+    struct invert_eval;
+
+    struct and_assign_eval;
+    struct or_assign_eval;
+    struct xor_assign_eval;
+    struct shift_left_assign_eval;
+    struct shift_right_assign_eval;
+
+    struct and_eval;
+    struct or_eval;
+    struct xor_eval;
+    struct shift_left_eval;
+    struct shift_right_eval;
+
+    BOOST_UNARY_RESULT_OF(~x, result_of_invert)
+
+    BOOST_BINARY_RESULT_OF(x &= y, result_of_and_assign)
+    BOOST_BINARY_RESULT_OF(x |= y, result_of_or_assign)
+    BOOST_BINARY_RESULT_OF(x ^= y, result_of_xor_assign)
+    BOOST_BINARY_RESULT_OF(x <<= y, result_of_shift_left_assign)
+    BOOST_BINARY_RESULT_OF(x >>= y, result_of_shift_right_assign)
+
+    BOOST_BINARY_RESULT_OF(x & y, result_of_and)
+    BOOST_BINARY_RESULT_OF(x | y, result_of_or)
+    BOOST_BINARY_RESULT_OF(x ^ y, result_of_xor)
+    BOOST_BINARY_RESULT_OF(x << y, result_of_shift_left)
+    BOOST_BINARY_RESULT_OF(x >> y, result_of_shift_right)
+
+#define x a0.eval(env)
+#define y a1.eval(env)
+
+    PHOENIX_UNARY_EVAL(invert_eval, result_of_invert, ~x)
+    PHOENIX_UNARY_COMPOSE(invert_eval, ~)
+
+    PHOENIX_BINARY_EVAL(and_assign_eval, result_of_and_assign, x &= y)
+    PHOENIX_BINARY_EVAL(or_assign_eval, result_of_or_assign, x |= y)
+    PHOENIX_BINARY_EVAL(xor_assign_eval, result_of_xor_assign, x ^= y)
+    PHOENIX_BINARY_EVAL(shift_left_assign_eval, result_of_shift_left_assign, x <<= y)
+    PHOENIX_BINARY_EVAL(shift_right_assign_eval, result_of_shift_right_assign, x >>= y)
+
+    PHOENIX_BINARY_EVAL(and_eval, result_of_and, x & y)
+    PHOENIX_BINARY_EVAL(or_eval, result_of_or, x | y)
+    PHOENIX_BINARY_EVAL(xor_eval, result_of_xor, x ^ y)
+    PHOENIX_BINARY_EVAL(shift_left_eval, result_of_shift_left, x << y)
+    PHOENIX_BINARY_EVAL(shift_right_eval, result_of_shift_right, x >> y)
+
+    PHOENIX_BINARY_COMPOSE(and_assign_eval, &=)
+    PHOENIX_BINARY_COMPOSE(or_assign_eval, |=)
+    PHOENIX_BINARY_COMPOSE(xor_assign_eval, ^=)
+    PHOENIX_BINARY_COMPOSE(shift_left_assign_eval, <<=)
+    PHOENIX_BINARY_COMPOSE(shift_right_assign_eval, >>=)
+
+    PHOENIX_BINARY_COMPOSE(and_eval, &)
+    PHOENIX_BINARY_COMPOSE(or_eval, |)
+    PHOENIX_BINARY_COMPOSE(xor_eval, ^)
+    PHOENIX_BINARY_COMPOSE(shift_left_eval, <<)
+    PHOENIX_BINARY_COMPOSE(shift_right_eval, >>)
+
+#undef x
+#undef y
+}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/comparison.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/comparison.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_COMPARISON_HPP
+#define PHOENIX_OPERATOR_COMPARISON_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_compose.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct equal_to_eval;
+    struct not_equal_to_eval;
+    struct less_eval;
+    struct less_equal_eval;
+    struct greater_eval;
+    struct greater_equal_eval;
+
+    BOOST_BINARY_RESULT_OF(x == y, result_of_equal_to)
+    BOOST_BINARY_RESULT_OF(x != y, result_of_not_equal_to)
+    BOOST_BINARY_RESULT_OF(x < y, result_of_less)
+    BOOST_BINARY_RESULT_OF(x <= y, result_of_less_equal)
+    BOOST_BINARY_RESULT_OF(x > y, result_of_greater)
+    BOOST_BINARY_RESULT_OF(x >= y, result_of_greater_equal)
+
+#define x a0.eval(env)
+#define y a1.eval(env)
+
+    PHOENIX_BINARY_EVAL(equal_to_eval, result_of_equal_to, x == y)
+    PHOENIX_BINARY_EVAL(not_equal_to_eval, result_of_not_equal_to, x != y)
+    PHOENIX_BINARY_EVAL(less_eval, result_of_less, x < y)
+    PHOENIX_BINARY_EVAL(less_equal_eval, result_of_less_equal, x <= y)
+    PHOENIX_BINARY_EVAL(greater_eval, result_of_greater, x > y)
+    PHOENIX_BINARY_EVAL(greater_equal_eval, result_of_greater_equal, x >= y)
+
+    PHOENIX_BINARY_COMPOSE(equal_to_eval, ==)
+    PHOENIX_BINARY_COMPOSE(not_equal_to_eval, !=)
+    PHOENIX_BINARY_COMPOSE(less_eval, <)
+    PHOENIX_BINARY_COMPOSE(less_equal_eval, <=)
+    PHOENIX_BINARY_COMPOSE(greater_eval, >)
+    PHOENIX_BINARY_COMPOSE(greater_equal_eval, >=)
+
+#undef x
+#undef y
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/binary_compose.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/binary_compose.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,32 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_DETAIL_BINARY_COMPOSE_HPP
+#define PHOENIX_OPERATOR_DETAIL_BINARY_COMPOSE_HPP
+
+#define PHOENIX_BINARY_COMPOSE(eval_name, op)                                   \
+    template <typename T0, typename T1>                                         \
+    inline actor<typename as_composite<eval_name, actor<T0>, actor<T1> >::type> \
+    operator op (actor<T0> const& a0, actor<T1> const& a1)                      \
+    {                                                                           \
+        return compose<eval_name>(a0, a1);                                      \
+    }                                                                           \
+                                                                                \
+    template <typename T0, typename T1>                                         \
+    inline actor<typename as_composite<eval_name, actor<T0>, T1>::type>         \
+    operator op (actor<T0> const& a0, T1 const& a1)                             \
+    {                                                                           \
+        return compose<eval_name>(a0, a1);                                      \
+    }                                                                           \
+                                                                                \
+    template <typename T0, typename T1>                                         \
+    inline actor<typename as_composite<eval_name, T0, actor<T1> >::type>        \
+    operator op (T0 const& a0, actor<T1> const& a1)                             \
+    {                                                                           \
+        return compose<eval_name>(a0, a1);                                      \
+    }
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/binary_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/binary_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,44 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_DETAIL_BINARY_EVAL_HPP
+#define PHOENIX_OPERATOR_DETAIL_BINARY_EVAL_HPP
+
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+#define PHOENIX_BINARY_EVAL(eval_name, op_result, expr)                         \
+    struct eval_name                                                            \
+    {                                                                           \
+        template <typename Env, typename A0, typename A1>                       \
+        struct result                                                            \
+        {                                                                       \
+            typedef typename A0::template result<Env>::type x_type;              \
+            typedef typename A1::template result<Env>::type y_type;              \
+                                                                                \
+            typedef typename                                                    \
+                mpl::eval_if<                                                   \
+                    mpl::or_<is_actor<x_type>, is_actor<y_type> >               \
+                  , re_curry<eval_name, x_type, y_type>                         \
+                  , op_result<x_type, y_type>                                   \
+                >::type                                                         \
+            type;                                                               \
+        };                                                                      \
+                                                                                \
+        template <typename RT, typename Env, typename A0, typename A1>          \
+        static RT                                                               \
+        eval(Env const& env, A0& a0, A1& a1)                                    \
+        {                                                                       \
+            return expr;                                                        \
+        }                                                                       \
+    };
+
+#undef x
+#undef y
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/io.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/io.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,78 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_DETAIL_IO_HPP
+#define PHOENIX_OPERATOR_DETAIL_IO_HPP
+
+#include <boost/spirit/home/phoenix/operator/bitwise.hpp>
+#include <boost/spirit/home/phoenix/core/reference.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <iostream>
+
+namespace boost { namespace phoenix { namespace detail
+{
+    typedef char(&no)[1];
+    typedef char(&yes)[2];
+
+    template <typename CharType, typename CharTrait>
+    yes ostream_test(std::basic_ostream<CharType, CharTrait>*);
+    no ostream_test(...);
+
+    template <typename CharType, typename CharTrait>
+    yes istream_test(std::basic_istream<CharType, CharTrait>*);
+    no istream_test(...);
+
+    template <typename T>
+    struct is_ostream
+    {
+        static T x;
+        BOOST_STATIC_CONSTANT(bool,
+            value = sizeof(detail::ostream_test(addressof(x))) == sizeof(yes));
+    };
+
+    template <typename T>
+    struct is_istream
+    {
+        static T x;
+        BOOST_STATIC_CONSTANT(bool,
+            value = sizeof(detail::istream_test(addressof(x))) == sizeof(yes));
+    };
+
+    template <typename T0, typename T1>
+    struct enable_if_ostream :
+        enable_if<
+            detail::is_ostream<T0>
+          , actor<
+                typename as_composite<
+                    shift_left_eval
+                  , actor<reference<T0> >
+                  , actor<T1>
+                >::type
+            >
+        >
+    {};
+
+    template <typename T0, typename T1>
+    struct enable_if_istream :
+        enable_if<
+            detail::is_istream<T0>
+          , actor<
+                typename as_composite<
+                    shift_right_eval
+                  , actor<reference<T0> >
+                  , actor<T1>
+                >::type
+            >
+        >
+    {};
+
+    typedef std::ios_base&  (*iomanip_type)(std::ios_base&);
+    typedef std::istream&   (*imanip_type)(std::istream&);
+    typedef std::ostream&   (*omanip_type)(std::ostream&);
+}}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,75 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_EVAL_HPP
+#define PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_EVAL_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+
+#include <boost/mpl/void.hpp>
+
+#include <boost/type_traits/function_traits.hpp>
+
+#include <boost/get_pointer.hpp>
+
+#include <boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_return.hpp>
+
+namespace boost { namespace phoenix {
+
+    struct mem_fun_ptr_eval
+    {
+        template<typename Env, typename PtrActor, typename MemFunPtrActor,
+                 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_SUB(PHOENIX_MEMBER_LIMIT, 2), typename Arg, mpl::void_)>
+
+        struct result
+            : detail::mem_fun_ptr_return<typename eval_result<MemFunPtrActor, Env>::type> { };
+
+        template<typename Rt, typename Env, typename PtrActor, typename MemFunPtrActor>
+        static typename result<Env,PtrActor,MemFunPtrActor>::type
+        eval(const Env& env, PtrActor& ptrActor, MemFunPtrActor& memFunPtrActor)
+        {
+            return (get_pointer(ptrActor.eval(env))->*memFunPtrActor.eval(env))();
+        }
+
+#define BOOST_PP_ITERATION_PARAMS_1                                                                                 \
+        (3, (1, BOOST_PP_SUB(PHOENIX_MEMBER_LIMIT, 2), "boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_eval.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+    };
+}}
+
+#endif
+
+#else
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+#define PHOENIX_EVAL_ARG(z,n,_) arg ## n.eval(env)        
+
+        template<typename Rt, typename Env, typename PtrActor, typename MemFunPtrActor,
+                 BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename Arg)> 
+        static typename result<Env,PtrActor,MemFunPtrActor, BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION,Arg)>::type
+        eval(const Env& env, PtrActor& ptrActor, MemFunPtrActor& memFunPtrActor,
+             BOOST_PP_ENUM_BINARY_PARAMS(PHOENIX_ITERATION, Arg, & arg))
+        {
+            return (get_pointer(ptrActor.eval(env))->*memFunPtrActor.eval(env))(
+                BOOST_PP_ENUM(PHOENIX_ITERATION,PHOENIX_EVAL_ARG,_));
+        }
+
+#undef PHOENIX_EVAL_ARG
+#undef PHOENIX_ITERATION
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_gen.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_gen.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,69 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_GEN_HPP
+#define PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_GEN_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/as_actor.hpp>
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+
+#include <boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_eval.hpp>
+
+namespace boost { namespace phoenix {
+    template<typename Actor, typename MemFunPtr>
+    struct mem_fun_ptr_gen
+    {
+        mem_fun_ptr_gen(
+            const Actor& actor, MemFunPtr memFunPtr)
+            : mActor(actor), mMemFunPtr(memFunPtr) { }
+
+        actor<typename as_composite<mem_fun_ptr_eval, Actor, typename as_actor<MemFunPtr>::type>::type>
+        operator()() const
+        {
+            return compose<mem_fun_ptr_eval>(
+                mActor, as_actor<MemFunPtr>::convert(mMemFunPtr));
+        }
+
+#define BOOST_PP_ITERATION_PARAMS_1                                                        \
+        (3, (1, BOOST_PP_SUB(PHOENIX_MEMBER_LIMIT, 2), "boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_gen.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+        Actor mActor;
+        MemFunPtr mMemFunPtr;
+    };
+}}
+
+#endif
+#else
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+        template<BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename Arg)>
+        actor<typename as_composite<
+            mem_fun_ptr_eval, Actor, typename as_actor<MemFunPtr>::type,
+            BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, Arg)>::type>
+        operator()(
+            BOOST_PP_ENUM_BINARY_PARAMS(PHOENIX_ITERATION, const Arg, &arg)) const
+        {
+            return compose<mem_fun_ptr_eval>(
+                mActor, as_actor<MemFunPtr>::convert(mMemFunPtr),
+                BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, arg));
+        }
+
+#undef PHOENIX_ITERATION
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_return.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_return.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,59 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_RETURN_HPP
+#define PHOENIX_OPERATOR_DETAIL_MEM_FUN_PTR_RETURN_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+
+namespace boost { namespace phoenix {
+namespace detail
+{
+    template<typename MemFunPtr>
+    struct mem_fun_ptr_return;
+
+    template<typename Ret, typename Class>
+    struct mem_fun_ptr_return<Ret (Class::*)()>
+    {
+        typedef Ret type;
+    };
+
+#define BOOST_PP_ITERATION_PARAMS_1                                                           \
+        (3, (1, PHOENIX_MEMBER_LIMIT, "boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_return.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+}
+}}
+
+#endif
+
+#else
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+    template<typename Ret, typename Class,
+             BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename T)>
+    struct mem_fun_ptr_return<Ret (Class::*)(BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, T))>
+    {
+        typedef Ret type;
+    };
+
+    template<typename Ret, typename Class,
+             BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename T)>
+    struct mem_fun_ptr_return<Ret (Class::*)(BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, T)) const>
+    {
+        typedef Ret type;
+    };
+
+#undef PHOENIX_ITERATION
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/unary_compose.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/unary_compose.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_DETAIL_UNARY_COMPOSE_HPP
+#define PHOENIX_OPERATOR_DETAIL_UNARY_COMPOSE_HPP
+
+#define PHOENIX_UNARY_COMPOSE(eval_name, op)                                    \
+    template <typename T0>                                                      \
+    inline actor<typename as_composite<eval_name, actor<T0> >::type>            \
+    operator op (actor<T0> const& a0)                                           \
+    {                                                                           \
+        return compose<eval_name>(a0);                                          \
+    }
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/detail/unary_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/detail/unary_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,40 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_DETAIL_UNARY_EVAL_HPP
+#define PHOENIX_OPERATOR_DETAIL_UNARY_EVAL_HPP
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+#define PHOENIX_UNARY_EVAL(eval_name, op_result, expr)                          \
+    struct eval_name                                                            \
+    {                                                                           \
+        template <typename Env, typename A0>                                    \
+        struct result                                                            \
+        {                                                                       \
+            typedef typename A0::template result<Env>::type x_type;              \
+                                                                                \
+            typedef typename                                                    \
+                mpl::eval_if<                                                   \
+                    is_actor<x_type>                                            \
+                  , re_curry<eval_name, x_type>                                 \
+                  , op_result<x_type>                                           \
+                >::type                                                         \
+            type;                                                               \
+        };                                                                      \
+                                                                                \
+        template <typename RT, typename Env, typename A0>                       \
+        static RT                                                               \
+        eval(Env const& env, A0& a0)                                            \
+        {                                                                       \
+            return expr;                                                        \
+        }                                                                       \
+    };
+
+#endif
+
+
Added: trunk/boost/spirit/home/phoenix/operator/if_else.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/if_else.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,78 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_IF_ELSE_HPP
+#define PHOENIX_OPERATOR_IF_ELSE_HPP
+
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+
+namespace boost { namespace phoenix
+{
+    BOOST_BINARY_RESULT_OF(true ? x : y, result_of_if_else)
+
+    struct if_else_op_eval
+    {
+        template <
+            typename Env
+          , typename Cond
+          , typename Then
+          , typename Else
+        >
+        struct result
+        {
+            typedef typename Then::template result<Env>::type then_type;
+            typedef typename Else::template result<Env>::type else_type;
+
+            typedef typename
+                result_of_if_else<then_type, else_type>::type
+            ite_result;
+
+            // Note: c ? x : y can return an lvalue! Allow if_else_op_eval
+            // to return an lvalue IFF then_type and else_type are both lvalues
+            // with the same type.
+
+            typedef typename
+                mpl::if_<
+                    mpl::and_<
+                        is_same<then_type, else_type>
+                      , is_reference<then_type>
+                    >
+                  , ite_result
+                  , typename remove_reference<ite_result>::type
+                >::type
+            type;
+        };
+
+        template <
+            typename RT
+          , typename Env
+          , typename Cond
+          , typename Then
+          , typename Else
+        >
+        static RT
+        eval(Env const& env, Cond& cond, Then& then, Else& else_)
+        {
+            return cond.eval(env) ? then.eval(env) : else_.eval(env);
+        }
+    };
+
+    template <typename Cond, typename Then, typename Else>
+    inline actor<typename as_composite<if_else_op_eval, Cond, Then, Else>::type>
+    if_else(Cond const& cond, Then const& then, Else const& else_)
+    {
+        return compose<if_else_op_eval>(cond, then, else_);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/io.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/io.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,71 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_IO_HPP
+#define PHOENIX_OPERATOR_IO_HPP
+
+#include <boost/spirit/home/phoenix/operator/detail/io.hpp>
+
+namespace boost { namespace phoenix
+{
+///////////////////////////////////////////////////////////////////////////////
+//
+//  overloads for std::basic_ostream and std::basic_istream
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <typename T0, typename T1>
+    inline typename detail::enable_if_ostream<T0, T1>::type
+    operator<<(T0& a0, actor<T1> const& a1)
+    {
+        return compose<shift_left_eval>(ref(a0), a1);
+    }
+
+    template <typename T0, typename T1>
+    inline typename detail::enable_if_istream<T0, T1>::type
+    operator>>(T0& a0, actor<T1> const& a1)
+    {
+        return compose<shift_right_eval>(ref(a0), a1);
+    }
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  overloads for I/O manipulators.
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <typename T0>
+    inline actor<typename as_composite<
+        shift_left_eval, actor<T0>, detail::omanip_type>::type>
+    operator<<(actor<T0> const& a0, detail::omanip_type a1)
+    {
+        return compose<shift_left_eval>(a0, a1);
+    }
+
+    template <typename T0>
+    inline actor<typename as_composite<
+        shift_left_eval, actor<T0>, detail::iomanip_type>::type>
+    operator<<(actor<T0> const& a0, detail::iomanip_type a1)
+    {
+        return compose<shift_left_eval>(a0, a1);
+    }
+
+    template <typename T0>
+    inline actor<typename as_composite<
+        shift_right_eval, actor<T0>, detail::imanip_type>::type>
+    operator>>(actor<T0> const& a0, detail::imanip_type a1)
+    {
+        return compose<shift_right_eval>(a0, a1);
+    }
+
+    template <typename T0>
+    inline actor<typename as_composite<
+        shift_right_eval, actor<T0>, detail::iomanip_type>::type>
+    operator>>(actor<T0> const& a0, detail::iomanip_type a1)
+    {
+        return compose<shift_right_eval>(a0, a1);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/logical.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/logical.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_LOGICAL_HPP
+#define PHOENIX_OPERATOR_LOGICAL_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_compose.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct logical_not_eval;
+    struct logical_and_eval;
+    struct logical_or_eval;
+
+    BOOST_UNARY_RESULT_OF(!x, result_of_logical_not)
+    BOOST_BINARY_RESULT_OF(x && y, result_of_logical_and)
+    BOOST_BINARY_RESULT_OF(x || y, result_of_logical_or)
+
+#define x a0.eval(env)
+#define y a1.eval(env)
+
+    PHOENIX_UNARY_EVAL(logical_not_eval, result_of_logical_not, !x)
+    PHOENIX_BINARY_EVAL(logical_and_eval, result_of_logical_and, x && y)
+    PHOENIX_BINARY_EVAL(logical_or_eval, result_of_logical_or, x || y)
+
+    PHOENIX_UNARY_COMPOSE(logical_not_eval, !)
+    PHOENIX_BINARY_COMPOSE(logical_and_eval, &&)
+    PHOENIX_BINARY_COMPOSE(logical_or_eval, ||)
+
+#undef x
+#undef y
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/member.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/member.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,151 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef PHOENIX_OPERATOR_MEMBER_HPP
+#define PHOENIX_OPERATOR_MEMBER_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_member_pointer.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/get_pointer.hpp>
+
+#include <boost/preprocessor/arithmetic/sub.hpp>
+
+#if !defined(PHOENIX_MEMBER_LIMIT)
+#define PHOENIX_MEMBER_LIMIT BOOST_PP_SUB(PHOENIX_COMPOSITE_LIMIT, 2)
+#endif
+
+#include <boost/spirit/home/phoenix/operator/detail/mem_fun_ptr_gen.hpp>
+
+#include <memory>
+
+namespace boost { 
+    template<typename T> class shared_ptr;
+    template<typename T> class scoped_ptr;
+
+namespace phoenix {
+    namespace detail
+    {
+        template<typename T>
+        struct member_type;
+        
+        template<typename Class, typename MemberType>
+        struct member_type<MemberType (Class::*)>
+        {
+            typedef MemberType type;
+        };
+    }
+
+    namespace meta
+    {
+        template<typename T> 
+        struct pointed_type;
+
+        template<typename T>
+        struct pointed_type<T*>
+        {
+            typedef T type;
+        };
+
+        template<typename T>
+        struct pointed_type<shared_ptr<T> >
+        {
+            typedef T type;
+        };
+        
+        template<typename T>
+        struct pointed_type<scoped_ptr<T> >
+        {
+            typedef T type;
+        };
+
+        template<typename T>
+        struct pointed_type<std::auto_ptr<T> >
+        {
+            typedef T type;
+        };
+    }
+
+    struct member_object_eval
+    {
+        template<typename Env, typename PtrActor, typename MemPtrActor>
+        struct result
+        {
+            typedef typename detail::member_type<
+                typename eval_result<MemPtrActor, Env>::type>::type member_type;
+
+            typedef typename meta::pointed_type<
+                typename remove_reference<
+                typename eval_result<PtrActor, Env>::type>::type>::type object_type;
+
+            typedef typename add_reference<
+                typename mpl::eval_if<
+                is_const<object_type>,
+                add_const<member_type>,
+                mpl::identity<member_type> >::type>::type type;
+        };
+
+        template<typename Rt, typename Env, typename PtrActor, typename MemPtrActor>
+        static typename result<Env,PtrActor,MemPtrActor>::type
+        eval(const Env& env, PtrActor& ptrActor, MemPtrActor& memPtrActor)
+        {
+            return get_pointer(ptrActor.eval(env))->*memPtrActor.eval(env);
+        }
+    };
+
+    namespace member_object
+    {
+        template<typename T0, typename MemObjPtr>
+        typename enable_if<
+            mpl::and_<is_member_pointer<MemObjPtr>, mpl::not_<is_member_function_pointer<MemObjPtr> > >,
+            actor<typename as_composite<
+            member_object_eval, actor<T0>,
+            typename as_actor<MemObjPtr>::type>::type> >::type
+        operator->*(
+            const actor<T0>& ptrActor, 
+            MemObjPtr memObjPtr)
+        {
+            return compose<member_object_eval>(
+                ptrActor,
+                as_actor<MemObjPtr>::convert(memObjPtr));
+        }
+    }
+
+    namespace member_function
+    {
+        template<typename T0, typename MemFunPtr>
+        typename enable_if<
+            is_member_function_pointer<MemFunPtr>,
+            mem_fun_ptr_gen<actor<T0>, MemFunPtr> >::type
+        operator->*(const actor<T0>& ptrActor, MemFunPtr memFunPtr)
+        {
+            return mem_fun_ptr_gen<actor<T0>, MemFunPtr>(
+                ptrActor, memFunPtr);
+        }
+    }
+
+    using member_object::operator->*;
+    using member_function::operator->*;
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/operator/self.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/operator/self.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,75 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_OPERATOR_SELF_HPP
+#define PHOENIX_OPERATOR_SELF_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/detail/type_deduction.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/unary_compose.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_eval.hpp>
+#include <boost/spirit/home/phoenix/operator/detail/binary_compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct reference_eval;
+    struct dereference_eval;
+    struct assign_eval;
+    struct index_eval;
+
+    BOOST_UNARY_RESULT_OF(&x, result_of_reference)
+    BOOST_UNARY_RESULT_OF(*x, result_of_dereference)
+    BOOST_BINARY_RESULT_OF(x = y, result_of_assign)
+    BOOST_ASYMMETRIC_BINARY_RESULT_OF(x[y], result_of_index)
+
+    namespace detail
+    {
+        template <typename T0, typename T1>
+        struct make_assign_composite
+        {
+            typedef actor<typename as_composite<assign_eval, T0, T1>::type> type;
+        };
+
+        template <typename T0, typename T1>
+        struct make_index_composite
+        {
+            typedef actor<typename as_composite<index_eval, T0, T1>::type> type;
+        };
+    }
+
+    template <typename Base>
+    template <typename T1>
+    typename detail::make_assign_composite<actor<Base>, T1>::type
+    actor<Base>::operator=(T1 const& a1) const
+    {
+        return compose<assign_eval>(*this, a1);
+    }
+
+    template <typename Base>
+    template <typename T1>
+    typename detail::make_index_composite<actor<Base>, T1>::type
+    actor<Base>::operator[](T1 const& a1) const
+    {
+        return compose<index_eval>(*this, a1);
+    }
+
+#define x a0.eval(env)
+#define y a1.eval(env)
+
+    PHOENIX_UNARY_EVAL(reference_eval, result_of_reference, &x)
+    PHOENIX_UNARY_EVAL(dereference_eval, result_of_dereference, *x)
+    PHOENIX_UNARY_COMPOSE(reference_eval, &)
+    PHOENIX_UNARY_COMPOSE(dereference_eval, *)
+
+    PHOENIX_BINARY_EVAL(assign_eval, result_of_assign, x = y)
+    PHOENIX_BINARY_EVAL(index_eval, result_of_index, x[y])
+}}
+
+#undef x
+#undef y
+#endif
Added: trunk/boost/spirit/home/phoenix/scope.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_SCOPE_HPP
+#define PHOENIX_SCOPE_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/scope/scoped_environment.hpp>
+#include <boost/spirit/home/phoenix/scope/lambda.hpp>
+#include <boost/spirit/home/phoenix/scope/let.hpp>
+#include <boost/spirit/home/phoenix/scope/local_variable.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/detail/local_gen.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/detail/local_gen.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,59 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_SCOPE_DETAIL_LOCAL_GEN_HPP
+#define PHOENIX_SCOPE_DETAIL_LOCAL_GEN_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+#define PHOENIX_LOCAL_GEN_PARAM(z, n, data)                                     \
+    actor<composite<assign_eval                                                 \
+  , fusion::vector<local_variable<K##n>, V##n> > > const& a##n
+
+#define PHOENIX_LOCAL_GEN_ACTOR(z, n, data)                                     \
+    fusion::at_c<1>(a##n)
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, PHOENIX_LOCAL_LIMIT,                                                \
+    "boost/spirit/home/phoenix/scope/detail/local_gen.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_LOCAL_GEN_PARAM
+#undef PHOENIX_LOCAL_GEN_ACTOR
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <
+        BOOST_PP_ENUM_PARAMS(N, typename K)
+      , BOOST_PP_ENUM_PARAMS(N, typename V)
+    >
+    PHOENIX_LOCAL_GEN_NAME<
+        fusion::vector<BOOST_PP_ENUM_PARAMS(N, V)>
+      , detail::map_local_index_to_tuple<BOOST_PP_ENUM_PARAMS(N, K)>
+    >
+    operator()(
+        BOOST_PP_ENUM(N, PHOENIX_LOCAL_GEN_PARAM, _)
+    ) const
+    {
+        return fusion::vector<BOOST_PP_ENUM_PARAMS(N, V)>(
+            BOOST_PP_ENUM(N, PHOENIX_LOCAL_GEN_ACTOR, _));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/scope/detail/local_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/detail/local_variable.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,217 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
+#define PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/preprocessor/enum.hpp>
+#include <boost/preprocessor/repeat.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/spirit/home/phoenix/detail/local_reference.hpp>
+
+#define PHOENIX_MAP_LOCAL_TEMPLATE_PARAM(z, n, data) \
+    typename T##n = unused<n>
+
+#define PHOENIX_MAP_LOCAL_DISPATCH(z, n, data)  \
+    typedef char(&result##n)[n+2];              \
+    static result##n get(T##n*);
+
+namespace boost { namespace phoenix
+{
+    template <typename Env, typename OuterEnv, typename Locals, typename Map>
+    struct scoped_environment;
+
+    namespace detail
+    {
+        template <typename Env>
+        struct initialize_local
+        {
+            template <class F>
+            struct result;
+
+            template <class F, class Actor>
+            struct result<F(Actor)>
+            {
+                typedef typename remove_reference<Actor>::type actor_type;
+                typedef typename actor_type::template result<Env>::type type;
+            };
+
+            initialize_local(Env const& env)
+                : env(env) {}
+
+            template <typename Actor>
+            typename result<initialize_local(Actor)>::type
+            operator()(Actor const& actor) const
+            {
+                return actor.eval(env);
+            }
+
+            Env const& env;
+        };
+
+        template <typename T>
+        struct is_scoped_environment : mpl::false_ {};
+
+        template <typename Env, typename OuterEnv, typename Locals, typename Map>
+        struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> >
+            : mpl::true_ {};
+
+        template <int N>
+        struct unused;
+
+        template <BOOST_PP_ENUM(
+            PHOENIX_LOCAL_LIMIT, PHOENIX_MAP_LOCAL_TEMPLATE_PARAM, _)>
+        struct map_local_index_to_tuple
+        {
+            typedef char(¬_found)[1];
+            static not_found get(...);
+
+            BOOST_PP_REPEAT(PHOENIX_LOCAL_LIMIT, PHOENIX_MAP_LOCAL_DISPATCH, _)
+        };
+
+        template<typename T>
+        T* generate_pointer();
+
+        template <typename Map, typename Tag>
+        struct get_index
+        {
+            BOOST_STATIC_CONSTANT(int,
+                value = (
+                    static_cast<int>((sizeof(Map::get(generate_pointer<Tag>()))) / sizeof(char)) - 2
+                ));
+
+            // if value == -1, Tag is not found
+            typedef mpl::int_<value> type;
+        };
+
+        template <typename Local, typename Env>
+        struct apply_local;
+
+        template <typename Local, typename Env>
+        struct outer_local
+        {
+            typedef typename
+                apply_local<Local, typename Env::outer_env_type>::type
+            type;
+        };
+
+        template <typename T>
+        struct local_reference_identity
+        {
+            typedef local_reference<T> type;
+        };
+
+        template <typename Locals, typename Index>
+        struct make_local_reference
+        {
+            typedef typename
+                fusion::result_of::value_at<Locals, Index>::type
+            value_at;
+
+            typedef typename
+                mpl::eval_if<
+                    is_reference<value_at>
+                  , mpl::identity<value_at>
+                  , local_reference_identity<value_at>
+                >::type
+            type;
+        };
+
+        template <typename Locals, typename Index>
+        struct get_local_or_void
+        {
+            typedef typename
+                mpl::eval_if<
+                    mpl::less<Index, mpl::size<Locals> >
+                  , make_local_reference<Locals, Index>
+                  , mpl::identity<fusion::void_>
+                >::type
+            type;
+        };
+
+        template <typename Local, typename Env, typename Index>
+        struct get_local_from_index
+        {
+            typedef typename
+                mpl::eval_if<
+                    mpl::equal_to<Index, mpl::int_<-1> >
+                  , outer_local<Local, Env>
+                  , get_local_or_void<typename Env::locals_type, Index>
+                >::type
+            type;
+        };
+
+        template <typename Local, typename Env>
+        struct get_local
+        {
+            typedef typename
+                get_index<
+                    typename Env::map_type, typename Local::key_type>::type
+            index_type;
+
+            typedef typename
+                get_local_from_index<Local, Env, index_type>::type
+            type;
+        };
+
+        template <typename Local, typename Env>
+        struct apply_local
+        {
+            // $$$ TODO: static assert that Env is a scoped_environment $$$
+            typedef typename get_local<Local, Env>::type type;
+        };
+
+        template <typename Key>
+        struct eval_local
+        {
+            template <typename RT, typename Env, typename Index>
+            static RT
+            get(Env const& env, Index, mpl::false_)
+            {
+                return RT(fusion::at<Index>(env.locals));
+            }
+
+            template <typename RT, typename Env, typename Index>
+            static RT
+            get(Env const& env, Index index, mpl::true_)
+            {
+                typedef typename
+                    get_index<typename Env::outer_env_type::map_type, Key>::type
+                index_type;
+
+                return get<RT>(
+                    env.outer_env
+                  , index_type()
+                  , mpl::equal_to<index_type, mpl::int_<-1> >());
+            }
+
+            template <typename RT, typename Env, typename Index>
+            static RT
+            get(Env const& env, Index index)
+            {
+                return get<RT>(
+                    env
+                  , index
+                  , mpl::equal_to<Index, mpl::int_<-1> >());
+            }
+        };
+    }
+}}
+
+#undef PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
+#undef PHOENIX_MAP_LOCAL_DISPATCH
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/dynamic.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/dynamic.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,197 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_DYNAMIC_HPP
+#define PHOENIX_SCOPE_DYNAMIC_HPP
+
+#if !defined(PHOENIX_DYNAMIC_LIMIT)
+# define PHOENIX_DYNAMIC_LIMIT PHOENIX_LIMIT
+#endif
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/inc.hpp>
+
+#include <boost/noncopyable.hpp>
+#include <boost/assert.hpp>
+
+#define PHOENIX_DYNAMIC_MEMBER(z, n, data)                                      \
+    typedef actor<dynamic_member<n, self_type> >                                \
+        BOOST_PP_CAT(member, BOOST_PP_INC(n));
+
+namespace boost { namespace phoenix
+{
+    template <typename DynamicScope>
+    struct dynamic_frame : noncopyable
+    {
+        typedef typename DynamicScope::tuple_type tuple_type;
+
+        dynamic_frame(DynamicScope const& scope)
+            : tuple()
+            , save(scope.frame)
+            , scope(scope)
+        {
+            scope.frame = this;
+        }
+
+        template <typename Tuple>
+        dynamic_frame(DynamicScope const& scope, Tuple const& init)
+            : tuple(init)
+            , save(scope.frame)
+            , scope(scope)
+        {
+            scope.frame = this;
+        }
+
+        ~dynamic_frame()
+        {
+            scope.frame = save;
+        }
+
+        tuple_type& data() { return tuple; }
+        tuple_type const& data() const { return tuple; }
+
+    private:
+
+        tuple_type tuple;
+        dynamic_frame* save;
+        DynamicScope const& scope;
+    };
+
+    template <int N, typename DynamicScope>
+    struct dynamic_member
+    {
+        typedef mpl::false_ no_nullary;
+        typedef typename DynamicScope::tuple_type tuple_type;
+
+        dynamic_member(DynamicScope const& scope)
+            : scope(scope) {}
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename
+                fusion::result_of::at_c<tuple_type, N>::type
+            type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& /*env*/) const
+        {
+            BOOST_ASSERT(scope.frame != 0);
+            return fusion::at_c<N>(scope.frame->data());
+        }
+
+    private:
+
+        DynamicScope const& scope;
+    };
+
+    template <BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(PHOENIX_LIMIT, typename T, void_)>
+    struct dynamic : noncopyable
+    {
+        typedef fusion::vector<BOOST_PP_ENUM_PARAMS(PHOENIX_LIMIT, T)> tuple_type;
+        typedef dynamic<BOOST_PP_ENUM_PARAMS(PHOENIX_LIMIT, T)> self_type;
+        typedef dynamic_frame<self_type> dynamic_frame_type;
+
+        dynamic()
+            : frame(0) {}
+
+        BOOST_PP_REPEAT(PHOENIX_LIMIT, PHOENIX_DYNAMIC_MEMBER, _)
+
+    private:
+
+        template <int N, typename DynamicScope>
+        friend struct dynamic_member;
+
+        template <typename DynamicScope>
+        friend struct dynamic_frame;
+
+        mutable dynamic_frame_type* frame;
+    };
+}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4355)
+#endif
+
+/*
+    PHOENIX_DYNAMIC macro(name, type-name sequence)
+    Example:
+
+    PHOENIX_DYNAMIC(
+        my_dynamic,
+            (int, num)
+            (std::string, message)
+            (double, real)
+    );
+
+    which expands to:
+
+    struct my_dynamic : ::boost::phoenix::dynamic<int, std::string, double>
+    {
+        my_dynamic() : num(*this), message(*this), real(*this) {}
+
+        member1 num;
+        member2 message;
+        member3 real;
+    };
+
+    PHOENIX_DYNAMIC takes the input (containing a binary sequence)
+    and converts that sequence to a unary sequence of
+    binary tuples and passes it on to PHOENIX_DYNAMIC_I.
+
+    Thanks to Paul Mensonides for the PP macro help
+*/
+
+#define PHOENIX_DYNAMIC(name, bseq)                                             \
+    PHOENIX_DYNAMIC_I(name, BOOST_PP_CAT(PHOENIX_DYNAMIC_X bseq, 0))            \
+
+#define PHOENIX_DYNAMIC_X(x, y) ((x, y)) PHOENIX_DYNAMIC_Y
+#define PHOENIX_DYNAMIC_Y(x, y) ((x, y)) PHOENIX_DYNAMIC_X
+#define PHOENIX_DYNAMIC_X0
+#define PHOENIX_DYNAMIC_Y0
+
+// PHOENIX_DYNAMIC_I generates the overarching structure and uses
+// SEQ_FOR_EACH_I to generate the "linear" substructures.
+
+#define PHOENIX_DYNAMIC_I(name, seq)                                            \
+    struct name :                                                               \
+        ::boost::phoenix::dynamic<                                              \
+            BOOST_PP_SEQ_FOR_EACH_I(PHOENIX_DYNAMIC_A, ~, seq)> {               \
+        name() : BOOST_PP_SEQ_FOR_EACH_I(PHOENIX_DYNAMIC_B, ~, seq) {}          \
+        BOOST_PP_SEQ_FOR_EACH_I(PHOENIX_DYNAMIC_C, ~, seq)                      \
+    }                                                                           \
+
+#define PHOENIX_DYNAMIC_A(r, _, i, xy)                                          \
+    BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 0, xy)                          \
+
+#define PHOENIX_DYNAMIC_B(r, _, i, xy)                                          \
+    BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 1, xy)(*this)                   \
+
+#define PHOENIX_DYNAMIC_C(r, _, i, xy)                                          \
+    BOOST_PP_CAT(member, BOOST_PP_INC(i)) BOOST_PP_TUPLE_ELEM(2, 1, xy);        \
+
+#undef PHOENIX_DYNAMIC_MEMBER
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/lambda.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/lambda.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,179 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_LAMBDA_HPP
+#define PHOENIX_SCOPE_LAMBDA_HPP
+
+#if !defined(PHOENIX_LOCAL_LIMIT)
+# define PHOENIX_LOCAL_LIMIT PHOENIX_LIMIT
+#endif
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/scope/scoped_environment.hpp>
+#include <boost/spirit/home/phoenix/scope/detail/local_variable.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename Base, typename OuterEnv, typename Locals, typename Map>
+    struct lambda_eval : Base
+    {
+        template <typename Env>
+        struct result
+        {
+            typedef typename Base::template
+                result<scoped_environment<Env, OuterEnv, Locals, Map> >::type
+            result_type;
+
+            typedef typename 
+                detail::unwrap_local_reference<result_type>::type 
+            type;
+        };
+
+        lambda_eval(
+            Base const& base
+          , OuterEnv const& outer_env
+          , Locals const& locals)
+            : Base(base)
+            , outer_env(outer_env)
+            , locals(locals) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            typedef typename result<Env>::type RT;
+            return RT(Base::eval(
+                scoped_environment<Env, OuterEnv, Locals, Map>(
+                    env, outer_env, locals)));
+        }
+
+        OuterEnv outer_env;
+        mutable Locals locals;
+    };
+    
+    template <typename Base, typename Vars, typename Map>
+    struct lambda_actor
+    {
+        typedef typename
+            mpl::fold<
+                Vars
+              , mpl::false_
+              , detail::compute_no_nullary
+            >::type
+        no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename 
+                fusion::result_of::as_vector<
+                    typename fusion::result_of::transform<
+                        Vars
+                      , detail::initialize_local<Env>
+                    >::type
+                >::type 
+            locals_type;
+
+            typedef actor<lambda_eval<Base, Env, locals_type, Map> > type;
+        };
+
+        lambda_actor(Base const& f, Vars const& vars)
+            : f(f), vars(vars) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            typedef typename result<Env>::type result_type;
+            
+            return result_type(
+                f, env, fusion::as_vector(
+                    fusion::transform(
+                        vars
+                      , detail::initialize_local<Env>(env)
+                    )));
+        }
+
+        Base f;
+        Vars vars;
+    };
+    
+    template <typename Vars, typename Map>
+    struct lambda_actor_gen
+    {
+        template <typename Base>
+        actor<lambda_actor<Base, Vars, Map> > const
+        operator[](actor<Base> const& f) const
+        {
+            return lambda_actor<Base, Vars, Map>(f, vars);
+        }
+
+        lambda_actor_gen(Vars const& vars)
+            : vars(vars) {}
+
+        Vars vars;
+    };
+
+    template <typename Key>
+    struct local_variable; // forward
+    struct assign_eval; // forward
+
+    struct lambda_gen 
+        : lambda_actor_gen<
+            fusion::vector<>
+          , detail::map_local_index_to_tuple<> >
+    {
+        typedef 
+            lambda_actor_gen<
+                fusion::vector<>
+              , detail::map_local_index_to_tuple<> >
+        base_type;
+
+        lambda_gen()
+            : base_type(fusion::vector<>())
+        {
+        }
+
+        template <typename K0, typename V0>
+        lambda_actor_gen<
+            fusion::vector<V0>
+          , detail::map_local_index_to_tuple<K0>
+        >
+        operator()(
+            actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
+        ) const
+        {
+            return fusion::vector<V0>(fusion::at_c<1>(a0));
+        }
+    
+        template <typename K0, typename K1, typename V0, typename V1>
+        lambda_actor_gen<
+            fusion::vector<V0, V1>
+          , detail::map_local_index_to_tuple<K0, K1>
+        >
+        operator()(
+            actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
+          , actor<composite<assign_eval, fusion::vector<local_variable<K1>, V1> > > const& a1
+        ) const
+        {
+            return fusion::vector<V0, V1>(fusion::at_c<1>(a0), fusion::at_c<1>(a1));
+        }
+        
+        // Bring in the rest...
+        #define PHOENIX_LOCAL_GEN_NAME lambda_actor_gen
+        #include <boost/spirit/home/phoenix/scope/detail/local_gen.hpp>
+        #undef PHOENIX_LOCAL_GEN_NAME
+    };
+
+    lambda_gen const lambda = lambda_gen();
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/let.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/let.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,148 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_LET_HPP
+#define PHOENIX_SCOPE_LET_HPP
+
+#if !defined(PHOENIX_LOCAL_LIMIT)
+# define PHOENIX_LOCAL_LIMIT PHOENIX_LIMIT
+#endif
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/scope/scoped_environment.hpp>
+#include <boost/spirit/home/phoenix/scope/detail/local_variable.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename Base, typename Vars, typename Map>
+    struct let_actor : Base
+    {
+        typedef typename
+            mpl::fold<
+                Vars
+              , mpl::false_
+              , detail::compute_no_nullary
+            >::type
+        no_nullary;
+        
+        template <typename Env>
+        struct result
+        {
+            typedef typename 
+                fusion::result_of::as_vector<
+                    typename fusion::result_of::transform<
+                        Vars
+                      , detail::initialize_local<Env>
+                    >::type
+                >::type 
+            locals_type;
+
+            typedef typename Base::template
+                result<scoped_environment<Env, Env, locals_type, Map> >::type
+            result_type;
+            
+            typedef typename 
+                detail::unwrap_local_reference<result_type>::type 
+            type;
+        };
+
+        let_actor(Base const& base, Vars const& vars)
+            : Base(base), vars(vars) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            typedef typename 
+                fusion::result_of::as_vector<
+                    typename fusion::result_of::transform<
+                        Vars
+                      , detail::initialize_local<Env>
+                    >::type
+                >::type 
+            locals_type;
+
+            locals_type locals = 
+                fusion::as_vector(
+                    fusion::transform(
+                        vars
+                      , detail::initialize_local<Env>(env)));
+            
+            typedef typename result<Env>::type RT;
+            return RT(Base::eval(
+                scoped_environment<Env, Env, locals_type, Map>(
+                    env
+                  , env
+                  , locals)));
+        }
+
+        Vars vars;
+    };
+    
+    template <typename Vars, typename Map>
+    struct let_actor_gen
+    {
+        template <typename Base>
+        actor<let_actor<Base, Vars, Map> > const
+        operator[](actor<Base> const& base) const
+        {
+            return let_actor<Base, Vars, Map>(base, vars);
+        }
+
+        let_actor_gen(Vars const& vars)
+            : vars(vars) {}
+
+        Vars vars;
+    };
+
+    template <typename Key>
+    struct local_variable; // forward
+    struct assign_eval; // forward
+
+    struct let_gen
+    {
+        template <typename K0, typename V0>
+        let_actor_gen<
+            fusion::vector<V0>
+          , detail::map_local_index_to_tuple<K0>
+        >
+        operator()(
+            actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
+        ) const
+        {
+            return fusion::vector<V0>(fusion::at_c<1>(a0));
+        }
+    
+        template <typename K0, typename K1, typename V0, typename V1>
+        let_actor_gen<
+            fusion::vector<V0, V1>
+          , detail::map_local_index_to_tuple<K0, K1>
+        >
+        operator()(
+            actor<composite<assign_eval, fusion::vector<local_variable<K0>, V0> > > const& a0
+          , actor<composite<assign_eval, fusion::vector<local_variable<K1>, V1> > > const& a1
+        ) const
+        {
+            return fusion::vector<V0, V1>(fusion::at_c<1>(a0), fusion::at_c<1>(a1));
+        }
+        
+        // Bring in the rest...
+        #define PHOENIX_LOCAL_GEN_NAME let_actor_gen
+        #include <boost/spirit/home/phoenix/scope/detail/local_gen.hpp>
+        #undef PHOENIX_LOCAL_GEN_NAME
+    };
+
+    let_gen const let = let_gen();
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/local_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/local_variable.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,111 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_LOCAL_VARIABLE_HPP
+#define PHOENIX_SCOPE_LOCAL_VARIABLE_HPP
+
+#if !defined(PHOENIX_LOCAL_LIMIT)
+# define PHOENIX_LOCAL_LIMIT PHOENIX_LIMIT
+#endif
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/spirit/home/phoenix/detail/local_reference.hpp>
+#include <boost/spirit/home/phoenix/scope/detail/local_variable.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename Key>
+    struct local_variable
+    {
+        typedef Key key_type;
+        
+        // This will prevent actor::operator()() from kicking in.
+        // Actually, we do not need all actor::operator()s for
+        // all arities, but this will suffice. The nullary 
+        // actor::operator() is particularly troublesome because 
+        // it is always eagerly evaluated by the compiler.
+        typedef mpl::true_ no_nullary; 
+        
+        template <typename Env>
+        struct result : detail::apply_local<local_variable<Key>, Env> {};
+
+        template <typename Env>
+        typename result<Env>::type const
+        eval(Env const& env) const
+        {
+            typedef typename result<Env>::type return_type;
+            typedef typename 
+                detail::get_index<typename Env::map_type, Key>::type 
+            index_type;
+            typedef detail::eval_local<Key> eval_local;
+
+            return eval_local::template get<return_type>(
+                env
+              , index_type());
+        }
+    };
+
+    namespace local_names
+    {
+        actor<local_variable<struct _a_key> > const _a 
+            = local_variable<struct _a_key>();
+        actor<local_variable<struct _b_key> > const _b 
+            = local_variable<struct _b_key>();
+        actor<local_variable<struct _c_key> > const _c 
+            = local_variable<struct _c_key>();
+        actor<local_variable<struct _d_key> > const _d 
+            = local_variable<struct _d_key>();
+        actor<local_variable<struct _e_key> > const _e 
+            = local_variable<struct _e_key>();
+        actor<local_variable<struct _f_key> > const _f 
+            = local_variable<struct _f_key>();
+        actor<local_variable<struct _g_key> > const _g 
+            = local_variable<struct _g_key>();
+        actor<local_variable<struct _h_key> > const _h 
+            = local_variable<struct _h_key>();
+        actor<local_variable<struct _i_key> > const _i 
+            = local_variable<struct _i_key>();
+        actor<local_variable<struct _j_key> > const _j 
+            = local_variable<struct _j_key>();
+        actor<local_variable<struct _k_key> > const _k 
+            = local_variable<struct _k_key>();
+        actor<local_variable<struct _l_key> > const _l 
+            = local_variable<struct _l_key>();
+        actor<local_variable<struct _m_key> > const _m 
+            = local_variable<struct _m_key>();
+        actor<local_variable<struct _n_key> > const _n 
+            = local_variable<struct _n_key>();
+        actor<local_variable<struct _o_key> > const _o 
+            = local_variable<struct _o_key>();
+        actor<local_variable<struct _p_key> > const _p 
+            = local_variable<struct _p_key>();
+        actor<local_variable<struct _q_key> > const _q 
+            = local_variable<struct _q_key>();
+        actor<local_variable<struct _r_key> > const _r 
+            = local_variable<struct _r_key>();
+        actor<local_variable<struct _s_key> > const _s 
+            = local_variable<struct _s_key>();
+        actor<local_variable<struct _t_key> > const _t 
+            = local_variable<struct _t_key>();
+        actor<local_variable<struct _u_key> > const _u 
+            = local_variable<struct _u_key>();
+        actor<local_variable<struct _v_key> > const _v 
+            = local_variable<struct _v_key>();
+        actor<local_variable<struct _w_key> > const _w 
+            = local_variable<struct _w_key>();
+        actor<local_variable<struct _x_key> > const _x 
+            = local_variable<struct _x_key>();
+        actor<local_variable<struct _y_key> > const _y 
+            = local_variable<struct _y_key>();
+        actor<local_variable<struct _z_key> > const _z 
+            = local_variable<struct _z_key>();
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/scope/scoped_environment.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/scope/scoped_environment.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2004 Daniel Wallin
+
+    Distributed under the 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_SCOPE_SCOPED_ENVIRONMENT_HPP
+#define PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP
+
+namespace boost { namespace phoenix
+{
+    template <typename Env, typename OuterEnv, typename Locals, typename Map>
+    struct scoped_environment
+    {
+        typedef Env env_type;
+        typedef OuterEnv outer_env_type;
+        typedef Locals locals_type;
+        typedef Map map_type;
+        typedef typename Env::args_type args_type;
+        typedef typename Env::tie_type tie_type;
+
+        scoped_environment(
+            Env const& env
+          , OuterEnv const& outer_env
+          , Locals& locals)
+            : env(env)
+            , outer_env(outer_env)
+            , locals(locals) {}
+
+        tie_type const& 
+        args() const
+        {
+            return env.args();
+        }
+
+        Env const& env;
+        OuterEnv const& outer_env;
+        Locals& locals;
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,20 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_HPP
+#define PHOENIX_STATEMENT_HPP
+
+#include <boost/spirit/home/phoenix/version.hpp>
+#include <boost/spirit/home/phoenix/statement/do_while.hpp>
+#include <boost/spirit/home/phoenix/statement/for.hpp>
+#include <boost/spirit/home/phoenix/statement/if.hpp>
+#include <boost/spirit/home/phoenix/statement/sequence.hpp>
+#include <boost/spirit/home/phoenix/statement/switch.hpp>
+#include <boost/spirit/home/phoenix/statement/while.hpp>
+#include <boost/spirit/home/phoenix/statement/throw.hpp>
+#include <boost/spirit/home/phoenix/statement/try_catch.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,101 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_STATEMENT_DETAIL_CATCH_ALL_EVAL_HPP
+#define PHOENIX_STATEMENT_DETAIL_CATCH_ALL_EVAL_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_defaults.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/mpl/void.hpp>
+
+namespace boost { namespace phoenix {
+    class catch_all_eval
+    {
+    public:
+        template<typename Env, typename TryBody, 
+                 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(PHOENIX_CATCH_LIMIT, typename CatchBody, mpl::void_),
+                 typename CatchAllBody = mpl::void_>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<typename Rt, typename Env, typename TryBody,
+                 typename CatchAllBody>
+        static void eval(
+            const Env& env, TryBody& tryBody, CatchAllBody& catchAllBody)
+        {
+            try
+            {
+                tryBody.eval(env);
+            }
+            catch(...)
+            {
+                catchAllBody.eval(env);
+            }
+        }
+
+#define BOOST_PP_ITERATION_PARAMS_1                                                        \
+        (3, (1, PHOENIX_CATCH_LIMIT, "boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+    };
+}}
+
+#endif
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+        template<typename Rt, typename Env, typename TryBody,
+                 BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename CatchBody),
+                 typename CatchAllBody>
+        static void eval(
+            const Env& env, TryBody& tryBody,
+            BOOST_PP_ENUM_BINARY_PARAMS(PHOENIX_ITERATION, CatchBody, catchBody),
+            CatchAllBody& catchAllBody)
+        {
+            try
+            {
+                tryBody.eval(env);
+            }
+
+#define BOOST_PP_ITERATION_PARAMS_2                                                                             \
+        (3, (0, BOOST_PP_SUB(PHOENIX_ITERATION, 1), "boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+            catch(...)
+            {
+                catchAllBody.eval(env);
+            }
+        }
+
+#undef PHOENIX_ITERATION
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+        catch(typename BOOST_PP_CAT(CatchBody, PHOENIX_ITERATION)::exception_type&)
+        {
+            BOOST_PP_CAT(catchBody, PHOENIX_ITERATION).eval(env);
+        }
+
+#undef PHOENIX_ITERATION
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/catch_composite.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/catch_composite.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,62 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef PHOENIX_STATEMENT_DETAIL_CATCH_COMPOSITE_HPP
+#define PHOENIX_STATEMENT_DETAIL_CATCH_COMPOSITE_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix {
+namespace detail
+{
+    struct catch_composite_eval
+    {
+        template<typename Env, typename Actor>
+        struct result :
+            eval_result<typename Actor::eval_type, Env> {};
+
+        template<typename Rt, typename Env, typename Actor>
+        static typename result<Env,Actor>::type
+        eval(const Env& env, Actor& actor)
+        {
+            return actor.eval(env);
+        }
+    };
+
+    template<typename Exception, typename Actor>
+    struct catch_composite :
+        composite<catch_composite_eval, fusion::vector<Actor> >
+    {
+        catch_composite(const Actor& actor)
+            : composite<catch_composite_eval, fusion::vector<Actor> >(actor) { }
+
+        typedef Exception exception_type;
+    };
+
+    template<typename Exception, typename Actor>
+    struct as_catch_actor
+    {
+        typedef catch_composite<
+            Exception,
+            Actor> comp;
+
+        typedef actor<comp> type;
+    };
+
+    template<typename Exception, typename Actor>
+    inline typename as_catch_actor<Exception, Actor>::type
+    catch_actor(const Actor& actor)
+    {
+        return catch_composite<Exception,Actor>(actor);
+    }
+}
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/catch_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/catch_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,79 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_STATEMENT_DETAIL_CATCH_EVAL_HPP
+#define PHOENIX_STATEMENT_DETAIL_CATCH_EVAL_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_defaults.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/mpl/void.hpp>
+
+namespace boost { namespace phoenix {
+    class catch_eval
+    {
+    public:
+        template<typename Env, typename TryBody, 
+                 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(PHOENIX_CATCH_LIMIT, typename CatchBody, mpl::void_)>
+        struct result
+        {
+            typedef void type;
+        };
+
+#define BOOST_PP_ITERATION_PARAMS_1                                                        \
+        (3, (1, PHOENIX_CATCH_LIMIT, "boost/spirit/home/phoenix/statement/detail/catch_eval.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+    };
+}}
+
+#endif
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+        template<typename Rt, typename Env, typename TryBody,
+                 BOOST_PP_ENUM_PARAMS(PHOENIX_ITERATION, typename CatchBody)>
+        static void eval(
+            const Env& env, TryBody& tryBody,
+            BOOST_PP_ENUM_BINARY_PARAMS(PHOENIX_ITERATION, CatchBody, catchBody))
+        {
+            try
+            {
+                tryBody.eval(env);
+            }
+
+#define BOOST_PP_ITERATION_PARAMS_2                                                                         \
+        (3, (0, BOOST_PP_SUB(PHOENIX_ITERATION, 1), "boost/spirit/home/phoenix/statement/detail/catch_eval.hpp"))
+
+#include BOOST_PP_ITERATE()
+
+        }
+
+#undef PHOENIX_ITERATION
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#define PHOENIX_ITERATION BOOST_PP_ITERATION()
+
+        catch(typename BOOST_PP_CAT(CatchBody, PHOENIX_ITERATION)::exception_type&)
+        {                                                         
+            BOOST_PP_CAT(catchBody, PHOENIX_ITERATION).eval(env);
+        }
+
+#undef PHOENIX_ITERATION
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/switch.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/switch.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,177 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
+#define PHOENIX_STATEMENT_DETAIL_SWITCH_HPP
+
+#include <boost/spirit/home/phoenix/core/nothing.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/push_back.hpp>
+#include <boost/fusion/include/push_front.hpp>
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/value_of.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost { namespace phoenix
+{
+
+    template <typename Actor, typename K, K Value>
+    struct switch_case;
+
+    template <typename Actor>
+    struct default_case;
+
+    namespace detail
+    {
+        template <typename T>
+        struct is_default_case : mpl::bool_<T::is_default> {};
+
+        template <typename A0, typename A1>
+        struct compose_case_a
+        {
+            // here, A0 and A1 are both switch cases
+            typedef typename
+                mpl::if_<
+                    is_default_case<A1>
+                  , fusion::vector<actor<A1>, actor<A0> >
+                  , fusion::vector<actor<A0>, actor<A1> >
+                >::type
+            type;
+
+            static type
+            eval(A0 const& _0, A1 const& _1, mpl::false_)
+            {
+                return type(_0, _1);
+            }
+
+            static type
+            eval(A0 const& _0, A1 const& _1, mpl::true_)
+            {
+                return type(_1, _0);
+            }
+
+            static type
+            eval(A0 const& _0, A1 const& _1)
+            {
+                return eval(_0, _1, is_default_case<A1>());
+            }
+        };
+
+        template <typename Seq, typename Case>
+        struct compose_case_b
+        {
+            typedef typename fusion::result_of::as_vector<
+                typename mpl::eval_if<
+                    is_default_case<Case>
+                  , fusion::result_of::push_front<Seq const, actor<Case> >
+                  , fusion::result_of::push_back<Seq const, actor<Case> >
+	        >::type>::type
+            type;
+
+            static type
+            eval(Seq const& seq, Case const& case_, mpl::false_)
+            {
+                return fusion::as_vector(
+		    		fusion::push_back(seq, actor<Case>(case_)));
+            }
+
+            static type
+            eval(Seq const& seq, Case const& case_, mpl::true_)
+            {
+                return fusion::as_vector(
+		    		fusion::push_front(seq, actor<Case>(case_)));
+            }
+
+            static type
+            eval(Seq const& seq, Case const& case_)
+            {
+                return eval(seq, case_, is_default_case<Case>());
+            }
+        };
+
+        template <typename Cases>
+        struct ensure_default
+        {
+            typedef
+                is_default_case<
+                    typename fusion::result_of::value_of<
+                        typename fusion::result_of::begin<Cases>::type
+                    >::type
+                >
+            is_default_case;
+
+            typedef typename
+                mpl::eval_if<
+                    is_default_case
+                  , mpl::identity<Cases>
+                  , fusion::result_of::push_front<
+                        Cases const, actor<default_case<actor<null_actor> > > >
+                >::type
+            type;
+
+            static type
+            eval(Cases const& cases, mpl::false_)
+            {
+                actor<default_case<actor<null_actor> > > default_
+                    = default_case<actor<null_actor> >(nothing);
+                return fusion::push_front(cases, default_);
+            }
+
+            static type
+            eval(Cases const& cases, mpl::true_)
+            {
+                return cases;
+            }
+
+            static type
+            eval(Cases const& cases)
+            {
+                return eval(cases, is_default_case());
+            }
+        };
+
+        template <typename Cond, typename Cases>
+        struct switch_composite
+        {
+            BOOST_STATIC_ASSERT(fusion::traits::is_sequence<Cases>::value);
+            typedef ensure_default<Cases> ensure_default;
+
+            typedef typename
+                fusion::result_of::as_vector<
+                    typename fusion::result_of::push_front<
+                        typename ensure_default::type, Cond>::type
+                    >::type
+            tuple_type;
+
+            typedef
+                composite<
+                    detail::switch_eval<fusion::result_of::size<tuple_type>::value-2>
+                  , tuple_type>
+            type;
+
+            static type
+            eval(Cond const& cond, Cases const& cases)
+            {
+                return fusion::as_vector(
+                    fusion::push_front(ensure_default::eval(cases), cond));
+            }
+        };
+
+        template <typename Cond, typename Cases>
+        struct switch_composite_actor
+        {
+            typedef actor<typename switch_composite<Cond, Cases>::type> type;
+        };
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,111 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_DETAIL_SWITCH_EVAL_HPP
+#define PHOENIX_STATEMENT_DETAIL_SWITCH_EVAL_HPP
+
+namespace boost { namespace phoenix { namespace detail
+{
+    template <int N>
+    struct switch_eval;
+
+    template <>
+    struct switch_eval<0>
+    {
+        template <
+            typename Env, typename Cond, typename Default
+        >
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env, typename Cond, typename Default
+        >
+        static void
+        eval(
+            Env const& env, Cond& cond, Default& default_
+        )
+        {
+            default_.eval(env);
+        }
+    };
+
+    template <>
+    struct switch_eval<1>
+    {
+        template <
+            typename Env, typename Cond, typename Default
+          , typename Case0
+        >
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env, typename Cond, typename Default
+          , typename Case0
+        >
+        static void
+        eval(
+            Env const& env, Cond& cond, Default& default_
+          , Case0& _0
+        )
+        {
+            switch (cond.eval(env))
+            {
+                case Case0::value:
+                    _0.eval(env);
+                    break;
+                default:
+                    default_.eval(env);
+            }
+        }
+    };
+
+    template <>
+    struct switch_eval<2>
+    {
+        template <
+            typename Env, typename Cond, typename Default
+          , typename Case0, typename Case1
+        >
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env, typename Cond, typename Default
+          , typename Case0, typename Case1
+        >
+        static void
+        eval(
+            Env const& env, Cond& cond, Default& default_
+          , Case0& _0, Case1& _1
+        )
+        {
+            switch (cond.eval(env))
+            {
+                case Case0::value:
+                    _0.eval(env);
+                    break;
+                case Case1::value:
+                    _1.eval(env);
+                    break;
+                default:
+                    default_.eval(env);
+            }
+        }
+    };
+
+    //  Bring in the rest of the switch_evals
+    #include <boost/spirit/home/phoenix/statement/detail/switch_eval.ipp>
+}}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/detail/switch_eval.ipp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,74 @@
+/*=============================================================================
+    Copyright (c) 2001-2006 Joel de Guzman
+
+    Use, modification and distribution is subject to the Boost Software
+    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+    http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef PHOENIX_STATEMENT_DETAIL_SWITCH_EVAL_IPP
+#define PHOENIX_STATEMENT_DETAIL_SWITCH_EVAL_IPP
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/repeat.hpp>
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define PHOENIX_CASE_ITEM(z, n, prefix)                                         \
+    case BOOST_PP_CAT(Case, n)::value:                                          \
+        BOOST_PP_CAT(_, n).eval(env);                                           \
+        break;
+
+#define BOOST_PP_ITERATION_PARAMS_1                                             \
+    (3, (3, BOOST_PP_DEC(BOOST_PP_DEC(PHOENIX_COMPOSITE_LIMIT)),                \
+    "boost/spirit/phoenix/statement/detail/switch_eval.ipp"))
+#include BOOST_PP_ITERATE()
+
+#undef PHOENIX_CASE_ITEM
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <>
+    struct switch_eval<N>
+    {
+        template <
+            typename Env, typename Cond, typename Default
+          , BOOST_PP_ENUM_PARAMS(N, typename Case)
+        >
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env, typename Cond, typename Default
+          , BOOST_PP_ENUM_PARAMS(N, typename Case)
+        >
+        static void
+        eval(Env const& env, Cond& cond, Default& default_
+          , BOOST_PP_ENUM_BINARY_PARAMS(N, Case, & _)
+        )
+        {
+            switch (cond.eval(env))
+            {
+                BOOST_PP_REPEAT(N, PHOENIX_CASE_ITEM, _)
+                default:
+                    default_.eval(env);
+            }
+        }
+    };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/phoenix/statement/do_while.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/do_while.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,62 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_DO_WHILE_HPP
+#define PHOENIX_STATEMENT_DO_WHILE_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct do_while_eval
+    {
+        template <typename Env, typename Cond, typename Do>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename RT, typename Env, typename Cond, typename Do>
+        static void
+        eval(Env const& env, Cond& cond, Do& do_)
+        {
+            do
+                do_.eval(env);
+            while (cond.eval(env));
+        }
+    };
+
+    template <typename Do>
+    struct do_while_gen
+    {
+        do_while_gen(Do const& do_)
+            : do_(do_) {}
+
+        template <typename Cond>
+        actor<typename as_composite<do_while_eval, Cond, Do>::type>
+        while_(Cond const& cond) const
+        {
+            return compose<do_while_eval>(cond, do_);
+        }
+
+        Do do_;
+    };
+
+    struct do_gen
+    {
+        template <typename Do>
+        do_while_gen<Do>
+        operator[](Do const& do_) const
+        {
+            return do_while_gen<Do>(do_);
+        }
+    };
+
+    do_gen const do_ = do_gen();
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/for.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/for.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,64 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_FOR_HPP
+#define PHOENIX_STATEMENT_FOR_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct for_eval
+    {
+        template <
+            typename Env
+          , typename Init, typename Cond, typename Step, typename Do>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env
+          , typename Init, typename Cond, typename Step, typename Do>
+        static void
+        eval(
+        	Env const& env
+          , Init& init, Cond& cond, Step& step, Do& do_)
+        {
+            for (init.eval(env); cond.eval(env); step.eval(env))
+                do_.eval(env);
+        }
+    };
+
+    template <typename Init, typename Cond, typename Step>
+    struct for_gen
+    {
+        for_gen(Init const& init, Cond const& cond, Step const& step)
+            : init(init), cond(cond), step(step) {}
+
+        template <typename Do>
+        actor<typename as_composite<for_eval, Init, Cond, Step, Do>::type>
+        operator[](Do const& do_) const
+        {
+            return compose<for_eval>(init, cond, step, do_);
+        }
+
+        Init init;
+        Cond cond;
+        Step step;
+    };
+
+    template <typename Init, typename Cond, typename Step>
+    inline for_gen<Init, Cond, Step>
+    for_(Init const& init, Cond const& cond, Step const& step)
+    {
+        return for_gen<Init, Cond, Step>(init, cond, step);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/if.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/if.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,122 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_IF_HPP
+#define PHOENIX_STATEMENT_IF_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/as_actor.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4355)
+#endif
+
+namespace boost { namespace phoenix
+{
+    struct if_else_eval
+    {
+        template <typename Env, typename Cond, typename Then, typename Else>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <
+            typename RT, typename Env
+          , typename Cond, typename Then, typename Else>
+        static void
+        eval(Env const& env, Cond& cond, Then& then, Else& else_)
+        {
+            if (cond.eval(env))
+                then.eval(env);
+            else
+                else_.eval(env);
+        }
+    };
+
+    struct if_eval
+    {
+        template <typename Env, typename Cond, typename Then>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename RT, typename Env, typename Cond, typename Then>
+        static void
+        eval(Env const& env, Cond& cond, Then& then)
+        {
+            if (cond.eval(env))
+                then.eval(env);
+        }
+    };
+
+    template <typename Cond, typename Then>
+    struct if_composite;
+
+    template <typename Cond, typename Then>
+    struct else_gen
+    {
+        else_gen(if_composite<Cond, Then> const& source)
+            : source(source) {}
+
+        template <typename Else>
+        actor<typename as_composite<if_else_eval, Cond, Then, Else>::type>
+        operator[](Else const& else_) const
+        {
+            return compose<if_else_eval>(
+                fusion::at_c<0>(source) // cond
+              , fusion::at_c<1>(source) // then
+              , else_ // else
+            );
+        }
+
+        if_composite<Cond, Then> const& source;
+    };
+
+    template <typename Cond, typename Then>
+    struct if_composite : composite<if_eval, fusion::vector<Cond, Then> >
+    {
+        if_composite(Cond const& cond, Then const& then)
+            : composite<if_eval, fusion::vector<Cond, Then> >(cond, then)
+            , else_(*this) {}
+
+        else_gen<Cond, Then> else_;
+    };
+
+    template <typename Cond>
+    struct if_gen
+    {
+        if_gen(Cond const& cond)
+            : cond(cond) {}
+
+        template <typename Then>
+        actor<if_composite<Cond, typename as_actor<Then>::type> >
+        operator[](Then const& then) const
+        {
+            return actor<if_composite<Cond, typename as_actor<Then>::type> >(
+                cond, as_actor<Then>::convert(then));
+        }
+
+        Cond cond;
+    };
+
+    template <typename Cond>
+    inline if_gen<typename as_actor<Cond>::type>
+    if_(Cond const& cond)
+    {
+        return if_gen<typename as_actor<Cond>::type>(
+            as_actor<Cond>::convert(cond));
+    }
+}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_SEQUENCE_HPP
+#define PHOENIX_STATEMENT_SEQUENCE_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct sequence_eval
+    {
+        template <typename Env, typename A0, typename A1>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename RT, typename Env, typename A0, typename A1>
+        static void
+        eval(Env const& env, A0& a0, A1& a1)
+        {
+            a0.eval(env);
+            a1.eval(env);
+        }
+    };
+    
+    namespace detail
+    {
+        template <typename BaseT0, typename BaseT1>
+        struct comma_result
+        {
+            typedef actor<
+                typename as_composite<
+                    sequence_eval
+                  , actor<BaseT0>
+                  , actor<BaseT1>
+                >::type
+            > type;
+        };
+    }
+
+    template <typename BaseT0, typename BaseT1>
+    inline typename detail::comma_result<BaseT0, BaseT1>::type
+    operator,(actor<BaseT0> const& a0, actor<BaseT1> const& a1)
+    {
+        return compose<sequence_eval>(a0, a1);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/switch.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/switch.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,151 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_SWITCH_HPP
+#define PHOENIX_STATEMENT_SWITCH_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+#include <boost/spirit/home/phoenix/core/nothing.hpp>
+#include <boost/spirit/home/phoenix/statement/detail/switch_eval.hpp>
+#include <boost/spirit/home/phoenix/statement/detail/switch.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/not.hpp>
+
+namespace boost { namespace phoenix
+{
+    template <typename Derived, typename Actor>
+    struct switch_case_base 
+    {
+        typedef Derived derived_t;
+        typedef Actor actor_t;
+        typedef typename Actor::no_nullary no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename Actor::eval_type::template result<Env>::type type;
+        };
+
+        switch_case_base(Actor const& actor)
+            : actor(actor) {}
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return actor.eval(env);
+        }
+
+        Actor actor;
+    };
+
+    template <typename Actor, typename K, K Value>
+    struct switch_case : switch_case_base<switch_case<Actor, K, Value>, Actor>
+    {
+        typedef switch_case_base<switch_case<Actor, K, Value>, Actor> base_t;
+        static K const value = Value;
+        static bool const is_default = false;
+
+        switch_case(Actor const& actor)
+            : base_t(actor) {}
+    };
+
+    template <typename Actor>
+    struct default_case : switch_case_base<default_case<Actor>, Actor>
+    {
+        typedef switch_case_base<default_case<Actor>, Actor> base_t;
+        static bool const is_default = true;
+
+        default_case(Actor const& actor)
+            : base_t(actor) {}
+    };
+
+    template <typename Cond>
+    struct switch_gen
+    {
+        switch_gen(Cond const& cond)
+            : cond(cond) {}
+
+        template <typename Cases>
+        typename lazy_enable_if<
+            fusion::traits::is_sequence<Cases>
+          , detail::switch_composite_actor<Cond, Cases>
+        >::type
+        operator[](Cases const& cases) const
+        {
+            typedef typename
+                detail::switch_composite<Cond, Cases>
+            switch_composite;
+            return switch_composite::eval(cond, cases);
+        }
+
+        template <typename D, typename A>
+        actor<typename detail::
+            switch_composite<Cond, fusion::vector<actor<D> > >::type>
+        operator[](switch_case_base<D, A> const& case_) const
+        {
+            typedef typename
+                detail::switch_composite<Cond, fusion::vector<actor<D> > >
+            switch_composite;
+            return switch_composite::eval(cond,
+                fusion::vector<actor<D> >(static_cast<D const&>(case_)));
+        }
+
+        Cond cond;
+    };
+
+    template <typename Cond>
+    inline switch_gen<typename as_actor<Cond>::type>
+    switch_(Cond const& cond)
+    {
+        return switch_gen<typename as_actor<Cond>::type>(
+            as_actor<Cond>::convert(cond));
+    }
+
+    template <int N, typename A0>
+    switch_case<typename as_actor<A0>::type, int, N>
+    case_(A0 const& _0)
+    {
+        return switch_case<typename as_actor<A0>::type, int, N>
+            (as_actor<A0>::convert(_0));
+    }
+
+    template <typename A0>
+    default_case<typename as_actor<A0>::type>
+    default_(A0 const& _0)
+    {
+        return default_case<typename as_actor<A0>::type>
+            (as_actor<A0>::convert(_0));
+    }
+
+    template <typename D0, typename A0, typename D1, typename A1>
+    inline typename detail::compose_case_a<D0, D1>::type
+    operator,(
+        switch_case_base<D0, A0> const& _0
+      , switch_case_base<D1, A1> const& _1
+    )
+    {
+        return detail::compose_case_a<D0, D1>::eval(
+            static_cast<D0 const&>(_0)
+          , static_cast<D1 const&>(_1)
+        );
+    }
+
+    template <typename Seq, typename D, typename A>
+    inline typename
+        lazy_enable_if<
+            fusion::traits::is_sequence<Seq>
+          , detail::compose_case_b<Seq, D>
+        >::type
+    operator,(Seq const& seq, switch_case_base<D, A> const& case_)
+    {
+        return detail::compose_case_b<Seq, D>::eval(
+            seq, static_cast<D const&>(case_));
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/throw.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/throw.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,66 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef PHOENIX_STATEMENT_THROW_HPP
+#define PHOENIX_STATEMENT_THROW_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace phoenix {
+
+    struct throw_new_eval
+    {
+        template<typename Env, typename ThrowExpr>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<typename Rt, typename Env, typename ThrowExpr>
+        static void 
+        eval(const Env& env, ThrowExpr& throwExpr)
+        {
+            throw throwExpr.eval(env);
+        }
+    };
+
+    struct throw_again_eval
+    {
+        typedef mpl::false_ no_nullary;
+
+        template<typename Env>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<typename Env>
+        void eval(const Env&) const
+        {
+            throw;
+        }
+    };
+
+    inline actor<throw_again_eval> throw_()
+    {
+        return throw_again_eval();
+    }
+
+    template<typename Actor>
+    actor<typename as_composite<throw_new_eval, Actor>::type>
+    throw_(const Actor& a)
+    {
+        return compose<throw_new_eval>(a);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/try_catch.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/try_catch.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,194 @@
+/*=============================================================================
+    Copyright (c) 2005-2007 Dan Marsden
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef PHOENIX_STATEMENT_TRY_CATCH_HPP
+#define PHOENIX_STATEMENT_TRY_CATCH_HPP
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+
+#include <boost/fusion/include/push_back.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+
+#include <boost/preprocessor/arithmetic/sub.hpp>
+
+#if !defined(PHOENIX_CATCH_LIMIT)
+#define PHOENIX_CATCH_LIMIT BOOST_PP_SUB(PHOENIX_COMPOSITE_LIMIT, 1)
+#endif
+
+#include <boost/spirit/home/phoenix/statement/detail/catch_composite.hpp>
+#include <boost/spirit/home/phoenix/statement/detail/catch_eval.hpp>
+#include <boost/spirit/home/phoenix/statement/detail/catch_all_eval.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4355)
+#endif
+
+namespace boost { namespace phoenix {
+
+    template<typename Tuple> struct try_catch_composite;
+
+    namespace meta
+    {
+        template<typename Composite, typename Actor>
+        struct try_catch_composite_push_back
+        {
+            typedef typename Composite::base_type actor_tuple;
+            typedef try_catch_composite<
+                typename fusion::result_of::as_vector<
+                typename fusion::result_of::push_back<
+                actor_tuple, Actor>::type>::type> type;
+        };
+
+        template<typename Composite, typename Actor>
+        struct catch_all_composite_push_back
+        {
+            typedef typename Composite::base_type actor_tuple;
+
+            typedef composite<
+                catch_all_eval,
+                typename fusion::result_of::as_vector<
+                typename fusion::result_of::push_back<
+                actor_tuple, Actor>::type>::type> type;
+        };
+    }
+
+    namespace detail
+    {
+        struct try_catch_composite_push_back
+        {
+            template<typename Composite, typename Actor>
+            struct result
+                : meta::try_catch_composite_push_back<Composite, Actor>
+            {};
+
+            template<typename Composite, typename Actor>
+            typename result<Composite, Actor>::type
+            operator()(
+                const Composite& composite, const Actor& actor) const
+            {
+                typedef typename result<Composite, Actor>::type result;
+                return result(
+                    fusion::as_vector(
+                        fusion::push_back(composite, actor)));
+            }
+        };
+
+        struct catch_all_composite_push_back
+        {
+            template<typename Composite, typename Actor>
+            struct result
+                : meta::catch_all_composite_push_back<Composite, Actor>
+            {};
+
+            template<typename Composite, typename Actor>
+            typename result<Composite, Actor>::type
+            operator()(
+                const Composite& composite, const Actor& actor) const
+            {
+                typedef typename result<Composite, Actor>::type result;
+                return result(
+                    fusion::as_vector(
+                        fusion::push_back(composite, actor)));
+            }
+        };
+
+    }
+
+    detail::try_catch_composite_push_back const try_catch_composite_push_back
+        = detail::try_catch_composite_push_back();
+    detail::catch_all_composite_push_back const catch_all_composite_push_back
+        = detail::catch_all_composite_push_back();
+
+    template<typename Exception, typename SourceComposite>
+    struct catch_gen
+    {
+        explicit catch_gen(
+            const SourceComposite& sourceComposite)
+            : mSourceComposite(sourceComposite) { }
+
+        template<typename Actor>
+        actor<typename meta::try_catch_composite_push_back<
+            SourceComposite,
+            detail::catch_composite<Exception, Actor> >::type>
+        operator[](const Actor& actor) const
+        {
+            return try_catch_composite_push_back(
+                mSourceComposite, detail::catch_composite<Exception, Actor>(actor));
+        }
+
+        const SourceComposite& mSourceComposite;
+    };
+
+    template<typename SourceComposite>
+    struct catch_all_gen
+    {
+        explicit catch_all_gen(
+            const SourceComposite& sourceComposite)
+            : mSourceComposite(sourceComposite) { }
+
+        template<typename Actor>
+        actor<typename meta::catch_all_composite_push_back<SourceComposite, Actor>::type>
+        operator[](const Actor& actor) const
+        {
+            return catch_all_composite_push_back(
+                mSourceComposite, actor);
+        }
+
+        const SourceComposite& mSourceComposite;
+    };
+
+    template<typename Tuple>
+    struct try_catch_composite
+        : composite<catch_eval, Tuple>
+    {
+        explicit try_catch_composite(
+            const Tuple& t)
+            :
+            composite<catch_eval, Tuple>(t),
+            catch_all(*this) { }
+
+        try_catch_composite(
+            const try_catch_composite& rhs)
+            : composite<catch_eval, Tuple>(rhs),
+              catch_all(*this) { }
+
+        template<typename Exception>
+        catch_gen<Exception, try_catch_composite> catch_() const
+        {
+            return catch_gen<Exception, try_catch_composite>(
+                *this);
+        }
+
+        const catch_all_gen<try_catch_composite> catch_all;
+
+    private:
+        try_catch_composite& operator=(const try_catch_composite&);
+    };
+
+    struct try_gen
+    {
+        template<typename Try>
+        try_catch_composite<fusion::vector<Try> > operator[](
+            const Try& try_) const
+        {
+            typedef fusion::vector<Try> tuple_type;
+            return try_catch_composite<tuple_type>(
+                tuple_type(try_));
+        }
+    };
+
+    try_gen const try_ = try_gen();
+}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/phoenix/statement/while.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/statement/while.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,56 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STATEMENT_WHILE_HPP
+#define PHOENIX_STATEMENT_WHILE_HPP
+
+#include <boost/spirit/home/phoenix/core/composite.hpp>
+#include <boost/spirit/home/phoenix/core/compose.hpp>
+
+namespace boost { namespace phoenix
+{
+    struct while_eval
+    {
+        template <typename Env, typename Cond, typename Do>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename RT, typename Env, typename Cond, typename Do>
+        static void
+        eval(Env const& env, Cond& cond, Do& do_)
+        {
+            while (cond.eval(env))
+                do_.eval(env);
+        }
+    };
+
+    template <typename Cond>
+    struct while_gen
+    {
+        while_gen(Cond const& cond)
+            : cond(cond) {}
+
+        template <typename Do>
+        actor<typename as_composite<while_eval, Cond, Do>::type>
+        operator[](Do const& do_) const
+        {
+            return compose<while_eval>(cond, do_);
+        }
+
+        Cond cond;
+    };
+
+    template <typename Cond>
+    inline while_gen<Cond>
+    while_(Cond const& cond)
+    {
+        return while_gen<Cond>(cond);
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,15 @@
+/*=============================================================================
+    Copyright (c) 2006 Daniel Wallin
+    Copyright (c) 2005 Dan Marsden
+    Copyright (c) 2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_ALGORITHM_HPP
+#define PHOENIX_ALGORITHM_HPP
+
+#include <boost/spirit/home/phoenix/stl/algorithm.hpp>
+#include <boost/spirit/home/phoenix/stl/container.hpp>
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+/*=============================================================================
+    Copyright (c) 2004 Angus Leeming
+    Copyright (c) 2006 Daniel Wallin
+    Copyright (c) 2005 Dan Marsden
+    Copyright (c) 2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STL_ALGORITHM_HPP
+#define PHOENIX_STL_ALGORITHM_HPP
+
+#include <boost/spirit/home/phoenix/stl/algorithm/iteration.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/querying.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/transformation.hpp>
+
+#endif // PHOENIX_STL_ALGORITHM_HPP
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,28 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_DETAIL_BEGIN_HPP
+#define PHOENIX_ALGORITHM_DETAIL_BEGIN_HPP
+
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/begin.hpp>
+
+namespace boost { namespace phoenix {
+namespace detail
+{
+  template<class R>
+  typename range_result_iterator<R>::type
+  begin_(R& r)
+  {
+      return boost::begin(r);
+  }
+}
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/decay_array.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/decay_array.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,30 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_DETAIL_DECAY_ARRAY_HPP
+#define PHOENIX_ALGORITHM_DETAIL_DECAY_ARRAY_HPP
+
+namespace boost { namespace phoenix {
+namespace detail
+{
+  template<typename T>
+  struct decay_array
+  {
+      typedef T type;
+  };
+
+  template<typename T, int N>
+  struct decay_array<T[N]>
+  {
+      typedef T* type;
+  };
+}
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,28 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_DETAIL_END_HPP
+#define PHOENIX_ALGORITHM_DETAIL_END_HPP
+
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/end.hpp>
+
+namespace boost { namespace phoenix {
+namespace detail
+{ 
+  template<class R>
+  typename range_result_iterator<R>::type
+  end_(R& r)
+  {
+      return boost::end(r);
+  }
+}
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_equal_range.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_equal_range.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_equal_range.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_EQUAL_RANGE_EN_14_12_2004
+#define HAS_EQUAL_RANGE_EN_14_12_2004
+
+#include <boost/mpl/or.hpp>
+#include "./is_std_map.hpp"
+#include "./is_std_set.hpp"
+#include "./is_std_hash_map.hpp"
+#include "./is_std_hash_set.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_equal_range
+        : boost::mpl::or_<
+            boost::mpl::or_<
+                is_std_map<T>
+              , is_std_multimap<T>
+              , is_std_set<T>
+              , is_std_multiset<T>
+            >
+          , boost::mpl::or_<
+                is_std_hash_map<T>
+              , is_std_hash_multimap<T>
+              , is_std_hash_set<T>
+              , is_std_hash_multiset<T>
+          >
+        >
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_find.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_find.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_find.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_FIND_EN_14_12_2004
+#define HAS_FIND_EN_14_12_2004
+
+#include <boost/mpl/or.hpp>
+#include "./is_std_map.hpp"
+#include "./is_std_set.hpp"
+#include "./is_std_hash_map.hpp"
+#include "./is_std_hash_set.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_find
+        : boost::mpl::or_<
+            boost::mpl::or_<
+                is_std_map<T>
+              , is_std_multimap<T>
+              , is_std_set<T>
+              , is_std_multiset<T>
+            >
+          , boost::mpl::or_<
+                is_std_hash_map<T>
+              , is_std_hash_multimap<T>
+              , is_std_hash_set<T>
+              , is_std_hash_multiset<T>
+          >
+        >
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_lower_bound.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_lower_bound.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_lower_bound.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_LOWER_BOUND_EN_14_12_2004
+#define HAS_LOWER_BOUND_EN_14_12_2004
+
+#include <boost/mpl/or.hpp>
+#include "./is_std_map.hpp"
+#include "./is_std_set.hpp"
+#include "./is_std_hash_map.hpp"
+#include "./is_std_hash_set.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_lower_bound
+        : boost::mpl::or_<
+            boost::mpl::or_<
+                is_std_map<T>
+              , is_std_multimap<T>
+              , is_std_set<T>
+              , is_std_multiset<T>
+            >
+          , boost::mpl::or_<
+                is_std_hash_map<T>
+              , is_std_hash_multimap<T>
+              , is_std_hash_set<T>
+              , is_std_hash_multiset<T>
+          >
+        >
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_remove.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_REMOVE_EN_14_12_2004
+#define HAS_REMOVE_EN_14_12_2004
+
+#include "./is_std_list.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_remove
+        : is_std_list<T>
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove_if.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_remove_if.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_remove_if.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_REMOVE_IF_EN_14_12_2004
+#define HAS_REMOVE_IF_EN_14_12_2004
+
+#include "./is_std_list.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_remove_if
+        : is_std_list<T>
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_reverse.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_reverse.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_reverse.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_REVERSE_EN_14_12_2004
+#define HAS_REVERSE_EN_14_12_2004
+
+#include "./is_std_list.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_reverse
+        : is_std_list<T>
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_sort.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_sort.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_sort.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_SORT_EN_14_12_2004
+#define HAS_SORT_EN_14_12_2004
+
+#include "./is_std_list.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_sort
+        : is_std_list<T>
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_unique.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_unique.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_unique.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_UNIQUE_EN_14_12_2004
+#define HAS_UNIQUE_EN_14_12_2004
+
+#include "./is_std_list.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_unique
+        : is_std_list<T>
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_upper_bound.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/has_upper_bound.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// has_upper_bound.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+#pragma once
+#endif
+
+#ifndef HAS_UPPER_BOUND_EN_14_12_2004
+#define HAS_UPPER_BOUND_EN_14_12_2004
+
+#include <boost/mpl/or.hpp>
+#include "./is_std_map.hpp"
+#include "./is_std_set.hpp"
+#include "./is_std_hash_map.hpp"
+#include "./is_std_hash_set.hpp"
+
+namespace boost
+{
+    // Specialize this for user-defined types
+    template<typename T>
+    struct has_upper_bound
+        : boost::mpl::or_<
+            boost::mpl::or_<
+                is_std_map<T>
+              , is_std_multimap<T>
+              , is_std_set<T>
+              , is_std_multiset<T>
+            >
+          , boost::mpl::or_<
+                is_std_hash_map<T>
+              , is_std_hash_multimap<T>
+              , is_std_hash_set<T>
+              , is_std_hash_multiset<T>
+          >
+        >
+    {
+    };
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_map.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// is_std_hash_map.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef IS_STD_HASH_MAP_EN_16_12_2004
+#define IS_STD_HASH_MAP_EN_16_12_2004
+
+#include <boost/mpl/bool.hpp>
+#include "./std_hash_map_fwd.hpp"
+
+namespace boost
+{
+    template<class T>
+    struct is_std_hash_map
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    struct is_std_hash_map< ::stdext::hash_map<Kty,Tr,Alloc> >
+        : boost::mpl::true_
+    {};
+
+    template<class T>
+    struct is_std_hash_multimap
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    struct is_std_hash_multimap< ::stdext::hash_multimap<Kty,Tr,Alloc> >
+        : boost::mpl::true_
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_hash_set.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// is_std_hash_set.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef IS_STD_HASH_SET_EN_16_12_2004
+#define IS_STD_HASH_SET_EN_16_12_2004
+
+#include <boost/mpl/bool.hpp>
+#include "./std_hash_set_fwd.hpp"
+
+namespace boost
+{
+    template<class T>
+    struct is_std_hash_set
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    struct is_std_hash_set< ::stdext::hash_set<Kty,Tr,Alloc> >
+        : boost::mpl::true_
+    {};
+
+    template<class T>
+    struct is_std_hash_multiset
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    struct is_std_hash_multiset< ::stdext::hash_multiset<Kty,Tr,Alloc> >
+        : boost::mpl::true_
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_list.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// is_std_list.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef IS_STD_LIST_EN_16_12_2004
+#define IS_STD_LIST_EN_16_12_2004
+
+#include <boost/mpl/bool.hpp>
+#include "./std_list_fwd.hpp"
+
+namespace boost
+{
+    template<class T>
+    struct is_std_list
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Ty
+      , class Alloc
+    >
+    struct is_std_list< ::std::list<Ty,Alloc> >
+        : boost::mpl::true_
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_map.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// is_std_map.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef IS_STD_MAP_EN_16_12_2004
+#define IS_STD_MAP_EN_16_12_2004
+
+#include <boost/mpl/bool.hpp>
+#include "./std_map_fwd.hpp"
+
+namespace boost
+{
+    template<class T>
+    struct is_std_map
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Ty
+      , class Pr
+      , class Alloc
+    >
+    struct is_std_map< ::std::map<Kty,Ty,Pr,Alloc> >
+        : boost::mpl::true_
+    {};
+
+    template<class T>
+    struct is_std_multimap
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Ty
+      , class Pr
+      , class Alloc
+    >
+    struct is_std_multimap< ::std::multimap<Kty,Ty,Pr,Alloc> >
+        : boost::mpl::true_
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/is_std_set.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// is_std_set.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef IS_STD_SET_EN_16_12_2004
+#define IS_STD_SET_EN_16_12_2004
+
+#include <boost/mpl/bool.hpp>
+#include "./std_set_fwd.hpp"
+
+namespace boost
+{
+    template<class T>
+    struct is_std_set
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Pr
+      , class Alloc
+    >
+    struct is_std_set< ::std::set<Kty,Pr,Alloc> >
+        : boost::mpl::true_
+    {};
+
+    template<class T>
+    struct is_std_multiset
+        : boost::mpl::false_
+    {};
+
+    template<
+        class Kty
+      , class Pr
+      , class Alloc
+    >
+    struct is_std_multiset< ::std::multiset<Kty,Pr,Alloc> >
+        : boost::mpl::true_
+    {};
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_map_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_map_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// std_hash_map_fwd.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef STD_HASH_MAP_FWD_EN_16_12_2004
+#define STD_HASH_MAP_FWD_EN_16_12_2004
+
+namespace stdext
+{
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    class hash_map;
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    class hash_multimap;
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_set_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_hash_set_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// std_hash_set_fwd.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef STD_HASH_SET_FWD_EN_16_12_2004
+#define STD_HASH_SET_FWD_EN_16_12_2004
+
+namespace stdext
+{
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    class hash_set;
+
+    template<
+        class Kty
+      , class Tr
+      , class Alloc
+    >
+    class hash_multiset;
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_list_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_list_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// std_list_fwd.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef STD_LIST_FWD_EN_16_12_2004
+#define STD_LIST_FWD_EN_16_12_2004
+
+namespace std
+{
+    template<
+        class Ty
+      , class Alloc
+    >
+    class list;
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_map_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_map_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// std_map_fwd.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef STD_MAP_FWD_EN_16_12_2004
+#define STD_MAP_FWD_EN_16_12_2004
+
+namespace std
+{
+    template<
+        class Kty
+      , class Ty
+      , class Pr
+      , class Alloc
+    >
+    class map;
+
+    template<
+        class Kty
+      , class Ty
+      , class Pr
+      , class Alloc
+    >
+    class multimap;
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_set_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/detail/std_set_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// std_set_fwd.hpp
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(_MSC_VER) && _MSC_VER >= 1000
+# pragma once
+#endif
+
+#ifndef STD_SET_FWD_EN_16_12_2004
+#define STD_SET_FWD_EN_16_12_2004
+
+namespace std
+{
+    template<
+        class Kty
+      , class Pr
+      , class Alloc
+    >
+	class set;
+
+    template<
+        class Kty
+      , class Pr
+      , class Alloc
+    >
+	class multiset;
+}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/iteration.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/iteration.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,69 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+// Copyright 2005 Dan Marsden. 
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_ITERATION_HPP
+#define PHOENIX_ALGORITHM_ITERATION_HPP
+
+#include <algorithm>
+#include <numeric>
+
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp>
+
+#include <boost/spirit/home/phoenix/function/function.hpp>
+
+namespace boost { namespace phoenix {
+namespace impl
+{
+    struct for_each
+    {
+        template<class R, class F>
+        struct result
+        {
+            typedef F type;
+        };
+
+        template<class R, class F>
+        F operator()(R& r, F fn) const
+        {        
+            return std::for_each(detail::begin_(r), detail::end_(r), fn);
+        }
+    };
+
+    struct accumulate
+    {
+        template<class R, class I, class C = void>
+        struct result
+        {
+            typedef I type;
+        };
+
+        template<class R, class I>
+        typename result<R,I>::type
+        operator()(R& r, I i) const
+        {
+            return std::accumulate(detail::begin_(r), detail::end_(r), i);
+        }
+
+        template<class R, class I, class C>
+        typename result<R,I,C>::type
+        operator()(R& r, I i, C c) const
+        {
+            return std::accumulate(detail::begin_(r), detail::end_(r), i, c);
+        }
+    };
+}
+
+function<impl::for_each> const for_each = impl::for_each();
+function<impl::accumulate> const accumulate = impl::accumulate();
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/querying.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/querying.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,502 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+// Copyright 2005 Dan Marsden. 
+// Copyright 2008 Hartmut Kaiser. 
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_QUERYING_HPP
+#define PHOENIX_ALGORITHM_QUERYING_HPP
+
+#include <algorithm>
+
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_find.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_lower_bound.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_upper_bound.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_equal_range.hpp>
+
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/decay_array.hpp>
+
+#include <boost/spirit/home/phoenix/function/function.hpp>
+
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/difference_type.hpp>
+
+namespace boost { namespace phoenix {
+namespace impl
+{
+    struct find
+    {
+        template<class R, class T>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& x, mpl::true_) const
+        {
+            return r.find(x);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& x, mpl::false_) const
+        {
+            return std::find(detail::begin_(r), detail::end_(r), x);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& x) const
+        {
+            return execute(r, x, has_find<R>());
+        }
+    };
+
+    struct find_if
+    {
+        template<class R, class P>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::find_if(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct find_end
+    {
+        template<class R, class R2, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class R2>
+        typename result<R, R2>::type operator()(R& r, R2& r2) const
+        {
+            return std::find_end(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                );
+        }
+
+        template<class R, class R2, class P>
+        typename result<R, R2, P>::type operator()(R& r, R2& r2, P p) const
+        {
+            return std::find_end(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                , p
+                );
+        }
+    };
+
+    struct find_first_of
+    {
+        template<class R, class R2, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class R2>
+        typename result<R, R2>::type operator()(R& r, R2& r2) const
+        {
+            return std::find_first_of(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                );
+        }
+
+        template<class R, class R2, class P>
+        typename result<R, R2, P>::type operator()(R& r, R2& r2, P p) const
+        {
+            return std::find_first_of(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                , p
+                );
+        }
+    };
+
+    struct adjacent_find
+    {
+        template<class R, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R>
+        typename result<R>::type operator()(R& r) const
+        {
+            return std::adjacent_find(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::adjacent_find(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct count
+    {
+        template<class R, class T>
+        struct result : range_difference<R>
+        {};
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& x) const
+        {
+            return std::count(detail::begin_(r), detail::end_(r), x);
+        }
+    };
+
+    struct count_if
+    {
+        template<class R, class P>
+        struct result : range_difference<R>
+        {};
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::count_if(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct distance
+    {
+        template<class R>
+        struct result : range_difference<R>
+        {};
+
+        template<class R>
+        typename result<R>::type operator()(R& r) const
+        {
+            return std::distance(detail::begin_(r), detail::end_(r));
+        }
+    };
+
+    struct equal
+    {
+        template<class R, class I, class P = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R, class I>
+        bool operator()(R& r, I i) const
+        {
+            return std::equal(detail::begin_(r), detail::end_(r), i);
+        }
+
+        template<class R, class I, class P>
+        bool operator()(R& r, I i, P p) const
+        {
+            return std::equal(detail::begin_(r), detail::end_(r), i, p);
+        }
+    };
+
+    struct search
+    {
+        template<class R, class R2, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class R2>
+        typename result<R, R2>::type operator()(R& r, R2& r2) const
+        {
+            return std::search(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                );
+        }
+
+        template<class R, class R2, class P>
+        typename result<R, R2, P>::type operator()(R& r, R2& r2, P p) const
+        {
+            return std::search(
+                detail::begin_(r)
+                , detail::end_(r)
+                , detail::begin_(r2)
+                , detail::end_(r2)
+                , p
+                );
+        }
+    };
+
+    struct lower_bound 
+    {
+        template<class R, class T, class C = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::true_) const
+        {
+            return r.lower_bound(val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::false_) const
+        {
+            return std::lower_bound(detail::begin_(r), detail::end_(r), val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& val) const
+        {
+            return execute(r, val, has_lower_bound<R>());
+        }
+
+        template<class R, class T, class C>
+        typename result<R, T>::type operator()(R& r, T const& val, C c) const
+        {
+            return std::lower_bound(detail::begin_(r), detail::end_(r), val, c);
+        }
+    };
+
+    struct upper_bound 
+    {
+        template<class R, class T, class C = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::true_) const
+        {
+            return r.upper_bound(val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::false_) const
+        {
+            return std::upper_bound(detail::begin_(r), detail::end_(r), val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& val) const
+        {
+            return execute(r, val, has_upper_bound<R>());
+        }
+
+        template<class R, class T, class C>
+        typename result<R, T>::type operator()(R& r, T const& val, C c) const
+        {
+            return std::upper_bound(detail::begin_(r), detail::end_(r), val, c);
+        }
+    };
+
+    struct equal_range 
+    {
+        template<class R, class T, class C = void>
+        struct result
+        {
+            typedef std::pair<
+                typename range_result_iterator<R>::type
+                , typename range_result_iterator<R>::type
+            > type;
+        };
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::true_) const
+        {
+            return r.equal_range(val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& val, mpl::false_) const
+        {
+            return std::equal_range(detail::begin_(r), detail::end_(r), val);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& val) const
+        {
+            return execute(r, val, has_equal_range<R>());
+        }
+
+        template<class R, class T, class C>
+        typename result<R, T>::type operator()(R& r, T const& val, C c) const
+        {
+            return std::equal_range(detail::begin_(r), detail::end_(r), val, c);
+        }
+    };
+
+    struct mismatch
+    {
+        template<class R, class I, class P = void>
+        struct result
+        {
+            typedef std::pair<
+                typename range_result_iterator<R>::type
+                , typename detail::decay_array<I>::type
+            > type;
+        };
+
+        template<class R, class I>
+        typename result<R, I>::type operator()(R& r, I i) const
+        {
+            return std::mismatch(detail::begin_(r), detail::end_(r), i);
+        }
+
+        template<class R, class I, class P>
+        typename result<R, I, P>::type operator()(R& r, I i, P p) const
+        {
+            return std::mismatch(detail::begin_(r), detail::end_(r), i, p);
+        }
+    };
+
+    struct binary_search 
+    {
+        template<class R, class T, class C = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R, class T>
+        bool operator()(R& r, T const& val) const
+        {
+            return std::binary_search(detail::begin_(r), detail::end_(r), val);
+        }
+
+        template<class R, class T, class C>
+        bool operator()(R& r, T const& val, C c) const
+        {
+            return std::binary_search(detail::begin_(r), detail::end_(r), val, c);
+        }
+    };
+
+    struct includes 
+    {
+        template<class R1, class R2, class C = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R1, class R2>
+        bool operator()(R1& r1, R2& r2) const
+        {
+            return std::includes(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                );
+        }
+
+        template<class R1, class R2, class C>
+        bool operator()(R1& r1, R2& r2, C c) const
+        {
+            return std::includes(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , c
+                );
+        }
+    };
+
+    struct min_element
+    {
+        template<class R, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R>
+        typename result<R>::type operator()(R& r) const
+        {
+            return std::min_element(detail::begin_(r), detail::end_(r));
+        }
+    
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::min_element(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct max_element
+    {
+        template<class R, class P = void>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R>
+        typename result<R>::type operator()(R& r) const
+        {
+            return std::max_element(detail::begin_(r), detail::end_(r));
+        }
+    
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::max_element(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct lexicographical_compare
+    {
+        template<class R1, class R2, class P = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R1, class R2>
+        typename result<R1, R2>::type operator()(R1& r1, R2& r2) const
+        {
+            return std::lexicographical_compare(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                );
+        }
+    
+        template<class R1, class R2, class P>
+        typename result<R1, R2>::type operator()(R1& r1, R2& r2, P p) const
+        {
+            return std::lexicographical_compare(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , p
+                );
+        }
+    };
+
+}
+
+function<impl::find> const find = impl::find();
+function<impl::find_if> const find_if = impl::find_if();
+function<impl::find_end> const find_end = impl::find_end();
+function<impl::find_first_of> const find_first_of = impl::find_first_of();
+function<impl::adjacent_find> const adjacent_find = impl::adjacent_find();
+function<impl::count> const count = impl::count();
+function<impl::count_if> const count_if = impl::count_if();
+function<impl::distance> const distance = impl::distance();
+function<impl::equal> const equal = impl::equal();
+function<impl::search> const search = impl::search();
+function<impl::lower_bound> const lower_bound = impl::lower_bound();
+function<impl::upper_bound> const upper_bound = impl::upper_bound();
+function<impl::equal_range> const equal_range = impl::equal_range();
+function<impl::mismatch> const mismatch = impl::mismatch();
+function<impl::binary_search> const binary_search = impl::binary_search();
+function<impl::includes> const includes = impl::includes();
+function<impl::min_element> const min_element = impl::min_element();
+function<impl::max_element> const max_element = impl::max_element();
+function<impl::lexicographical_compare> const lexicographical_compare = impl::lexicographical_compare();
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/algorithm/transformation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/algorithm/transformation.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,1071 @@
+// Copyright 2005 Daniel Wallin. 
+// Copyright 2005 Joel de Guzman.
+// Copyright 2005 Dan Marsden. 
+//
+// Use, modification and distribution is subject to the Boost Software 
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Modeled after range_ex, Copyright 2004 Eric Niebler
+
+#ifndef PHOENIX_ALGORITHM_TRANSFORMATION_HPP
+#define PHOENIX_ALGORITHM_TRANSFORMATION_HPP
+
+#include <algorithm>
+#include <numeric>
+
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_sort.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_remove.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_remove_if.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_unique.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_reverse.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/has_sort.hpp>
+
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/begin.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/end.hpp>
+#include <boost/spirit/home/phoenix/stl/algorithm/detail/decay_array.hpp>
+
+#include <boost/spirit/home/phoenix/function/function.hpp>
+
+#include <boost/range/result_iterator.hpp>
+#include <boost/range/difference_type.hpp>
+
+#include <boost/mpl/if.hpp>
+
+#include <boost/type_traits/is_void.hpp>
+
+namespace boost { namespace phoenix { namespace impl
+{
+    struct swap
+    {
+        template <class A, class B>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <class A, class B>
+        void operator()(A& a, B& b) const
+        {
+            using std::swap;
+            swap(a, b);
+        }
+    };
+
+    struct copy
+    {
+        template<class R, class I>
+        struct result
+            : detail::decay_array<I>
+        {};
+
+        template<class R, class I>
+        typename result<R,I>::type
+        operator()(R& r, I i) const
+        {
+            return std::copy(detail::begin_(r), detail::end_(r), i);
+        }
+    };
+
+    struct copy_backward
+    {
+        template<class R, class I>
+        struct result
+        {
+            typedef I type;
+        };
+
+        template<class R, class I>
+        I operator()(R& r, I i) const
+        {
+            return std::copy_backward(detail::begin_(r), detail::end_(r), i);
+        }
+    };
+
+    struct transform
+    {
+        template<class R, class OutorI1, class ForOut, class BinF = void>
+        struct result
+            : detail::decay_array<
+            typename mpl::if_<is_void<BinF>, OutorI1, ForOut>::type>
+        {
+        };
+
+        template<class R, class O, class F>
+        typename result<R,O,F>::type
+        operator()(R& r, O o, F f) const
+        {
+            return std::transform(detail::begin_(r), detail::end_(r), o, f);
+        }
+
+        template<class R, class I, class O, class F>
+        typename result<R,I,O,F>::type
+        operator()(R& r, I i, O o, F f) const
+        {
+            return std::transform(detail::begin_(r), detail::end_(r), i, o, f);
+        }
+    };
+
+    struct replace
+    {
+        template<class R, class T, class T2>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class T>
+        void operator()(R& r, T const& what, T const& with) const
+        {
+            std::replace(detail::begin_(r), detail::end_(r), what, with);
+        }
+    };
+
+    struct replace_if
+    {
+        template<class R, class P, class T>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class P, class T>
+        void operator()(R& r, P p, T const& with) const
+        {
+            std::replace_if(detail::begin_(r), detail::end_(r), p, with);
+        }
+    };
+
+    struct replace_copy
+    {
+        template<class R, class O, class T, class T2>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O, class T>
+        typename result<R,O,T,T>::type 
+        operator()(R& r, O o, T const& what, T const& with) const
+        {
+            return std::replace_copy(detail::begin_(r), detail::end_(r), o, what, with);
+        }
+    };
+
+    struct replace_copy_if
+    {
+        template<class R, class O, class P, class T>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O, class P, class T>
+        typename result<R,O,P,T>::type
+        operator()(R& r, O o, P p, T const& with) const
+        {
+            return std::replace_copy_if(detail::begin_(r), detail::end_(r), o, p, with);
+        }
+    };
+
+    struct fill
+    {
+        template<class R, class T>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class T>
+        void operator()(R& r, T const& x) const
+        {
+            std::fill(detail::begin_(r), detail::end_(r), x);
+        }
+    };
+
+    struct fill_n
+    {
+        template<class R, class N, class T>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class N, class T>
+        void operator()(R& r, N n, T const& x) const
+        {
+            std::fill_n(detail::begin_(r), n, x);
+        }
+    };
+
+    struct generate
+    {
+        template<class R, class G>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class G>
+        void operator()(R& r, G g) const
+        {
+            std::generate(detail::begin_(r), detail::end_(r), g);
+        }
+    };
+
+    struct generate_n
+    {
+        template<class R, class N, class G>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class N, class G>
+        void operator()(R& r, N n, G g) const
+        {
+            std::generate_n(detail::begin_(r), n, g);
+        }
+    };
+
+    struct remove
+    {
+        template<class R, class T>
+        struct result : range_result_iterator<R>
+        {
+        };
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& x, mpl::true_) const
+        {
+            r.remove(x);
+            return detail::end_(r);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type execute(R& r, T const& x, mpl::false_) const
+        {
+            return std::remove(detail::begin_(r), detail::end_(r), x);
+        }
+
+        template<class R, class T>
+        typename result<R, T>::type operator()(R& r, T const& x) const
+        {
+            return execute(r, x, has_remove<R>());
+        }
+    };
+
+    struct remove_if
+    {
+        template<class R, class P>
+        struct result : range_result_iterator<R>
+        {
+        };
+
+        template<class R, class P>
+        typename result<R, P>::type execute(R& r, P p, mpl::true_) const
+        {
+            r.remove_if(p);
+            return detail::end_(r);
+        }
+
+        template<class R, class P>
+        typename result<R, P>::type execute(R& r, P p, mpl::false_) const
+        {
+            return std::remove_if(detail::begin_(r), detail::end_(r), p);
+        }
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return execute(r, p, has_remove_if<R>());
+        }
+    };
+
+    struct remove_copy
+    {
+        template<class R, class O, class T>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O, class T>
+        typename result<R,O,T>::type
+        operator()(R& r, O o, T const& x) const
+        {
+            return std::remove_copy(detail::begin_(r), detail::end_(r), o, x);
+        }
+    };
+
+    struct remove_copy_if
+    {
+        template<class R, class O, class P>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O, class P>
+        typename result<R,O,P>::type
+        operator()(R& r, O o, P p) const
+        {
+            return std::remove_copy_if(detail::begin_(r), detail::end_(r), o, p);
+        }
+    };
+
+    struct unique
+    {
+        template<class R, class P = void>
+        struct result : range_result_iterator<R>
+        {
+        };
+
+        template<class R>
+        typename result<R>::type execute(R& r, mpl::true_) const
+        {
+            r.unique();
+            return detail::end_(r);
+        }
+
+        template<class R>
+        typename result<R>::type execute(R& r, mpl::false_) const
+        {
+            return std::unique(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R>
+        typename result<R>::type operator()(R& r) const
+        {
+            return execute(r, has_unique<R>());
+        }
+
+
+        template<class R, class P>
+        typename result<R>::type execute(R& r, P p, mpl::true_) const
+        {
+            r.unique(p);
+            return detail::end_(r);
+        }
+
+        template<class R, class P>
+        typename result<R, P>::type execute(R& r, P p, mpl::false_) const
+        {
+            return std::unique(detail::begin_(r), detail::end_(r), p);
+        }
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return execute(r, p, has_unique<R>());
+        }
+    };
+
+    struct unique_copy
+    {
+        template<class R, class O, class P = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O>
+        typename result<R, O>::type operator()(R& r, O o) const
+        {
+            return std::unique_copy(
+                detail::begin_(r)
+                , detail::end_(r)
+                , o
+                );
+        }
+
+        template<class R, class O, class P>
+        typename result<R, O, P>::type operator()(R& r, O o, P p) const
+        {
+            return std::unique_copy(
+                detail::begin_(r)
+                , detail::end_(r)
+                , o
+                , p
+                );
+        }
+    };
+
+    struct reverse
+    {
+        template<class R>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void execute(R& r, mpl::true_) const
+        {
+            r.reverse();
+        }
+
+        template<class R>
+        void execute(R& r, mpl::false_) const
+        {
+            std::reverse(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            execute(r, has_reverse<R>());
+        }
+    };
+
+    struct reverse_copy
+    {
+        template<class R, class O>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class O>
+        typename result<R, O>::type operator()(R& r, O o) const
+        {
+            return std::reverse_copy(
+                detail::begin_(r)
+                , detail::end_(r)
+                , o
+                );
+        }
+    };
+
+    struct rotate
+    {
+        template<class R, class M>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class M>
+        void operator()(R& r, M m) const
+        {
+            std::rotate(
+                detail::begin_(r)
+                , m
+                , detail::end_(r)
+                );
+        }
+    };
+
+    struct rotate_copy
+    {
+        template<class R, class M, class O>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R, class M, class O>
+        typename result<R, M, O>::type operator()(R& r, M m, O o) const
+        {
+            return std::rotate_copy(
+                detail::begin_(r)
+                , m
+                , detail::end_(r)
+                , o
+                );
+        }
+    };
+
+    struct random_shuffle
+    {
+        template<class R, class G = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            return std::random_shuffle(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class G>
+        void operator()(R& r, G g) const
+        {
+            return std::random_shuffle(detail::begin_(r), detail::end_(r), g);
+        }
+    };
+
+    struct partition
+    {
+        template<class R, class P>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::partition(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct stable_partition
+    {
+        template<class R, class P>
+        struct result : range_result_iterator<R>
+        {};
+
+        template<class R, class P>
+        typename result<R, P>::type operator()(R& r, P p) const
+        {
+            return std::stable_partition(detail::begin_(r), detail::end_(r), p);
+        }
+    };
+
+    struct sort
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void execute(R& r, mpl::true_) const
+        {
+            r.sort();
+        }
+
+        template<class R>
+        void execute(R& r, mpl::false_) const
+        {
+            std::sort(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            execute(r, has_sort<R>());
+        }
+
+        template<class R, class C>
+        void execute(R& r, C c, mpl::true_) const
+        {
+            r.sort(c);
+        }
+
+        template<class R, class C>
+        void execute(R& r, C c, mpl::false_) const
+        {
+            std::sort(detail::begin_(r), detail::end_(r), c);
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            execute(r, c, has_sort<R>());
+        }
+    };
+
+    struct stable_sort
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            std::stable_sort(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            std::stable_sort(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct partial_sort
+    {
+        template<class R, class M, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class M>
+        void operator()(R& r, M m) const
+        {
+            std::partial_sort(detail::begin_(r), m, detail::end_(r));
+        }
+
+        template<class R, class M, class C>
+        void operator()(R& r, M m, C c) const
+        {
+            std::partial_sort(detail::begin_(r), m, detail::end_(r), c);
+        }
+    };
+
+    struct partial_sort_copy
+    {
+        template<class R1, class R2, class C = void>
+        struct result : range_result_iterator<R2>
+        {};
+
+        template<class R1, class R2>
+        typename result<R1, R2>::type operator()(R1& r1, R2& r2) const
+        {
+            return std::partial_sort_copy(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                );
+        }
+
+        template<class R1, class R2, class C>
+        typename result<R1, R2>::type operator()(R1& r1, R2& r2, C c) const
+        {
+            return std::partial_sort_copy(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , c
+                );
+        }
+    };
+
+    struct nth_element
+    {
+        template<class R, class N, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class N>
+        void operator()(R& r, N n) const
+        {
+            return std::nth_element(detail::begin_(r), n, detail::end_(r));
+        }
+
+        template<class R, class N, class C>
+        void operator()(R& r, N n, C c) const
+        {
+            return std::nth_element(detail::begin_(r), n, detail::end_(r), c);
+        }
+    };
+
+    struct merge 
+    {
+        template<class R1, class R2, class O, class C = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R1, class R2, class O>
+        typename result<R1, R2, O>::type operator()(R1& r1, R2& r2, O o) const
+        {
+            return std::merge(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                );
+        }
+
+        template<class R1, class R2, class O, class C>
+        typename result<R1, R2, O, C>::type operator()(R1& r1, R2& r2, O o, C c) const
+        {
+            return std::merge(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                , c
+                );
+        }
+    };
+
+    struct inplace_merge 
+    {
+        template<class R, class M, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R, class M>
+        void operator()(R& r, M m) const
+        {
+            return std::inplace_merge(detail::begin_(r), m, detail::end_(r));
+        }
+
+        template<class R, class M, class C>
+        void operator()(R& r, M m, C c) const
+        {
+            return std::inplace_merge(detail::begin_(r), m, detail::end_(r), c);
+        }
+    };
+
+    struct next_permutation
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R>
+        bool operator()(R& r) const
+        {
+            return std::next_permutation(detail::begin_(r), detail::end_(r));
+        }
+    
+        template<class R, class C>
+        bool operator()(R& r, C c) const
+        {
+            return std::next_permutation(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct prev_permutation
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef bool type;
+        };
+
+        template<class R>
+        bool operator()(R& r) const
+        {
+            return std::prev_permutation(detail::begin_(r), detail::end_(r));
+        }
+    
+        template<class R, class C>
+        bool operator()(R& r, C c) const
+        {
+            return std::prev_permutation(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+
+    struct inner_product
+    {
+        template<class R, class I, class T, class C1 = void, class C2 = void>
+        struct result
+        {
+            typedef T type;
+        };
+
+        template<class R, class I, class T>
+        typename result<R,I,T>::type
+        operator()(R& r, I i, T t) const
+        {
+            return std::inner_product(
+                detail::begin_(r), detail::end_(r), i, t);
+        }
+
+        template<class R, class I, class T, class C1, class C2>
+        typename result<R,I,T,C1,C2>::type
+        operator()(R& r, I i, T t, C1 c1, C2 c2) const
+        {
+            return std::inner_product(
+                detail::begin_(r), detail::end_(r), i, 
+                t, c1, c2);
+        }
+    };
+
+    struct partial_sum
+    {
+        template<class R, class I, class C = void>
+        struct result
+            : detail::decay_array<I>
+        {};
+
+        template<class R, class I>
+        typename result<R,I>::type
+        operator()(R& r, I i) const
+        {
+            return std::partial_sum(
+                detail::begin_(r), detail::end_(r), i);
+        }
+
+        template<class R, class I, class C>
+        typename result<R,I,C>::type
+        operator()(R& r, I i, C c) const
+        {
+            return std::partial_sum(
+                detail::begin_(r), detail::end_(r), i, c);
+        }
+    };
+
+    struct adjacent_difference
+    {
+        template<class R, class I, class C = void>
+        struct result
+            : detail::decay_array<I>
+        {};
+
+        template<class R, class I>
+        typename result<R,I>::type
+        operator()(R& r, I i) const
+        {
+            return std::adjacent_difference(
+                detail::begin_(r), detail::end_(r), i);
+        }
+
+        template<class R, class I, class C>
+        typename result<R,I,C>::type
+        operator()(R& r, I i, C c) const
+        {
+            return std::adjacent_difference(
+                detail::begin_(r), detail::end_(r), i, c);
+        }    
+    };
+
+    struct push_heap
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            std::push_heap(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            std::push_heap(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct pop_heap
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            std::pop_heap(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            std::pop_heap(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct make_heap
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            std::make_heap(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            std::make_heap(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct sort_heap
+    {
+        template<class R, class C = void>
+        struct result
+        {
+            typedef void type;
+        };
+
+        template<class R>
+        void operator()(R& r) const
+        {
+            std::sort_heap(detail::begin_(r), detail::end_(r));
+        }
+
+        template<class R, class C>
+        void operator()(R& r, C c) const
+        {
+            std::sort_heap(detail::begin_(r), detail::end_(r), c);
+        }
+    };
+
+    struct set_union
+    {
+        template<class R1, class R2, class O, class C = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R1, class R2, class O>
+        typename result<R1, R2, O>::type operator()(R1& r1, R2& r2, O o) const
+        {
+            return std::set_union(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                );
+        }
+
+        template<class R1, class R2, class O, class C>
+        typename result<R1, R2, O, C>::type operator()(R1& r1, R2& r2, O o, C c) const
+        {
+            return std::set_union(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                , c
+                );
+        }
+    };
+
+    struct set_intersection
+    {
+        template<class R1, class R2, class O, class C = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R1, class R2, class O>
+        typename result<R1, R2, O>::type operator()(R1& r1, R2& r2, O o) const
+        {
+            return std::set_intersection(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                );
+        }
+
+        template<class R1, class R2, class O, class C>
+        typename result<R1, R2, O, C>::type operator()(R1& r1, R2& r2, O o, C c) const
+        {
+            return std::set_intersection(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                , c
+                );
+        }
+    };
+
+    struct set_difference
+    {
+        template<class R1, class R2, class O, class C = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R1, class R2, class O>
+        typename result<R1, R2, O>::type operator()(R1& r1, R2& r2, O o) const
+        {
+            return std::set_difference(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                );
+        }
+
+        template<class R1, class R2, class O, class C>
+        typename result<R1, R2, O, C>::type operator()(R1& r1, R2& r2, O o, C c) const
+        {
+            return std::set_difference(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                , c
+                );
+        }
+    };
+
+    struct set_symmetric_difference
+    {
+        template<class R1, class R2, class O, class C = void>
+        struct result
+            : detail::decay_array<O>
+        {};
+
+        template<class R1, class R2, class O>
+        typename result<R1, R2, O>::type operator()(R1& r1, R2& r2, O o) const
+        {
+            return std::set_symmetric_difference(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                );
+        }
+
+        template<class R1, class R2, class O, class C>
+        typename result<R1, R2, O, C>::type operator()(R1& r1, R2& r2, O o, C c) const
+        {
+            return std::set_symmetric_difference(
+                detail::begin_(r1), detail::end_(r1)
+                , detail::begin_(r2), detail::end_(r2)
+                , o
+                , c
+                );
+        }
+    };
+
+}}} // boost::phoenix::impl
+
+namespace boost { namespace phoenix
+{
+    function<impl::swap> const swap = impl::swap();
+    function<impl::copy> const copy = impl::copy();
+    function<impl::copy_backward> const copy_backward = impl::copy_backward();
+    function<impl::transform> const transform = impl::transform();
+    function<impl::replace> const replace = impl::replace();
+    function<impl::replace_if> const replace_if = impl::replace_if();
+    function<impl::replace_copy> const replace_copy = impl::replace_copy();
+    function<impl::replace_copy_if> const replace_copy_if = impl::replace_copy_if();
+    function<impl::fill> const fill = impl::fill();
+    function<impl::fill_n> const fill_n = impl::fill_n();
+    function<impl::generate> const generate = impl::generate();
+    function<impl::generate_n> const generate_n = impl::generate_n();
+    function<impl::remove> const remove = impl::remove();
+    function<impl::remove_if> const remove_if = impl::remove_if();
+    function<impl::remove_copy> const remove_copy = impl::remove_copy();
+    function<impl::remove_copy_if> const remove_copy_if = impl::remove_copy_if();
+    function<impl::unique> const unique = impl::unique();
+    function<impl::unique_copy> const unique_copy = impl::unique_copy();
+    function<impl::reverse> const reverse = impl::reverse();
+    function<impl::reverse_copy> const reverse_copy = impl::reverse_copy();
+    function<impl::rotate> const rotate = impl::rotate();
+    function<impl::rotate_copy> const rotate_copy = impl::rotate_copy();
+    function<impl::random_shuffle> const random_shuffle = impl::random_shuffle();
+    function<impl::partition> const partition = impl::partition();
+    function<impl::stable_partition> const stable_partition = impl::stable_partition();
+    function<impl::sort> const sort = impl::sort();
+    function<impl::stable_sort> const stable_sort = impl::stable_sort();
+    function<impl::partial_sort> const partial_sort = impl::partial_sort();
+    function<impl::partial_sort_copy> const partial_sort_copy = impl::partial_sort_copy();
+    function<impl::nth_element> const nth_element = impl::nth_element();
+    function<impl::merge> const merge = impl::merge();
+    function<impl::inplace_merge> const inplace_merge = impl::inplace_merge();
+    function<impl::next_permutation> const next_permutation = impl::next_permutation();
+    function<impl::prev_permutation> const prev_permutation = impl::prev_permutation();
+    function<impl::inner_product> const inner_product = impl::inner_product();
+    function<impl::partial_sum> const partial_sum = impl::partial_sum();
+    function<impl::adjacent_difference> const adjacent_difference = impl::adjacent_difference();
+    function<impl::push_heap> const push_heap = impl::push_heap();
+    function<impl::pop_heap> const pop_heap = impl::pop_heap();
+    function<impl::make_heap> const make_heap = impl::make_heap();
+    function<impl::sort_heap> const sort_heap = impl::sort_heap();
+    function<impl::set_union> const set_union = impl::set_union();
+    function<impl::set_intersection> const set_intersection = impl::set_intersection();
+    function<impl::set_difference> const set_difference = impl::set_difference();
+    function<impl::set_symmetric_difference> const set_symmetric_difference = impl::set_symmetric_difference();
+}}
+
+#endif
Added: trunk/boost/spirit/home/phoenix/stl/container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/container.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,13 @@
+/*=============================================================================
+    Copyright (c) 2004 Angus Leeming
+    Copyright (c) 2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STL_CONTAINER_HPP
+#define PHOENIX_STL_CONTAINER_HPP
+
+#include <boost/spirit/home/phoenix/stl/container/container.hpp>
+
+#endif // PHOENIX_STL_CONTAINER_HPP
Added: trunk/boost/spirit/home/phoenix/stl/container/container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/container/container.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,712 @@
+/*=============================================================================
+    Copyright (c) 2004 Angus Leeming
+    Copyright (c) 2004 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_STL_CONTAINER_CONTAINER_HPP
+#define PHOENIX_STL_CONTAINER_CONTAINER_HPP
+
+#include <boost/spirit/home/phoenix/core/limits.hpp>
+
+#if (PHOENIX_LIMIT < 5)
+# error "PHOENIX_LIMIT is set too low"
+#endif
+
+#include <boost/spirit/home/phoenix/stl/container/detail/container.hpp>
+#include <boost/spirit/home/phoenix/function/function.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+namespace boost { namespace phoenix
+{
+///////////////////////////////////////////////////////////////////////////////
+//
+//  STL container member functions
+//
+//      Lazy functions for STL container member functions
+//
+//      These functions provide a mechanism for the lazy evaluation of the
+//      public member functions of the STL containers. For an overview of
+//      what is meant by 'lazy evaluation', see the comments in operators.hpp
+//      and functions.hpp.
+//
+//      Lazy functions are provided for all of the member functions of the
+//      following containers:
+//
+//      deque · list · map · multimap · vector.
+//
+//      Indeed, should *your* class have member functions with the same names
+//      and signatures as those listed below, then it will automatically be
+//      supported. To summarize, lazy functions are provided for member
+//      functions:
+//
+//          assign · at · back · begin · capacity · clear · empty · end ·
+//          erase · front · get_allocator · insert · key_comp · max_size ·
+//          pop_back · pop_front · push_back · push_front · rbegin · rend ·
+//          reserve · resize . size · splice · value_comp.
+//
+//      The lazy functions' names are the same as the corresponding member
+//      function. Sample usage:
+//
+//      "Normal" version                 "Lazy" version
+//      ----------------                 --------------
+//      my_vector.at(5)                  phoenix::at(arg1, 5)
+//      my_list.size()                   phoenix::size(arg1)
+//      my_vector1.swap(my_vector2)      phoenix::swap(arg1, arg2)
+//
+//      Notice that member functions with names that clash with a
+//      function in stl algorithms are absent. This will be provided
+//      in Phoenix's algorithm module.
+//
+//      No support is provided here for lazy versions of operator+=,
+//      operator[] etc. Such operators are not specific to STL containers and
+//      lazy versions can therefore be found in operators.hpp.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Lazy member function implementaions.
+//
+//      The structs below provide the guts of the implementation. Thereafter,
+//      the corresponding lazy function itself is simply:
+//
+//          function<stl::assign> const assign = stl::assign();
+//
+//      The structs provide a nested "result" class template whose
+//      "type" typedef enables the lazy function to ascertain the type
+//      to be returned when it is invoked.
+//
+//      They also provide operator() member functions with signatures
+//      corresponding to those of the underlying member function of
+//      the STL container.
+//
+///////////////////////////////////////////////////////////////////////////////
+    namespace stl
+    {
+        struct assign
+        {
+            template <
+                typename C
+              , typename Arg1 = fusion::void_
+              , typename Arg2 = fusion::void_
+              , typename Arg3 = fusion::void_
+            >
+            struct result
+            {
+                typedef typename add_reference<C>::type type;
+            };
+
+            template <typename C, typename Arg1>
+            C& operator()(C& c, Arg1 const& arg1) const
+            {
+                c.assign(arg1);
+                return c;
+            }
+
+            template <typename C, typename Arg1, typename Arg2>
+            C& operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
+            {
+                c.assign(arg1, arg2);
+                return c;
+            }
+
+            template <typename C, typename Arg1, typename Arg2, typename Arg3>
+            C& operator()(
+                C& c
+              , Arg1 const& arg1
+              , Arg2 const& arg2
+              , Arg3 const& arg3) const
+            {
+                return c.assign(arg1, arg2, arg3);
+            }
+        };
+
+        struct at
+        {
+            template <typename C, typename Index>
+            struct result
+            {
+                typedef typename const_qualified_reference_of<C>::type type;
+            };
+
+            template <typename C, typename Index>
+            typename result<C, Index>::type
+            operator()(C& c, Index const& i) const
+            {
+                return c.at(i);
+            }
+        };
+
+        struct back
+        {
+            template <typename C>
+            struct result
+            {
+                typedef 
+                    typename const_qualified_reference_of<C>::type
+                type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.back();
+            }
+        };
+
+        struct begin
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename const_qualified_iterator_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.begin();
+            }
+        };
+
+        struct capacity
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename size_type_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C const& c) const
+            {
+                return c.capacity();
+            }
+        };
+
+        struct clear
+        {
+            template <typename C>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C>
+            void operator()(C& c) const
+            {
+                return c.clear();
+            }
+        };
+
+        struct empty
+        {
+            template <typename C>
+            struct result
+            {
+                typedef bool type;
+            };
+
+            template <typename C>
+            bool operator()(C const& c) const
+            {
+                return c.empty();
+            }
+        };
+
+        struct end
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename const_qualified_iterator_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.end();
+            }
+        };
+
+        struct erase
+        {
+            //  This mouthful can differentiate between the generic erase
+            //  functions (Container == std::deque, std::list, std::vector) and
+            //  that specific to the two map-types, std::map and std::multimap.
+            //
+            //  where C is a std::deque, std::list, std::vector:
+            //
+            //      1) iterator C::erase(iterator where);
+            //      2) iterator C::erase(iterator first, iterator last);
+            //
+            //  where M is a std::map or std::multimap:
+            //
+            //      3) size_type M::erase(const Key& keyval);
+            //      4) void M::erase(iterator where);
+            //      5) void M::erase(iterator first, iterator last);
+
+            template <typename C, typename Arg1, typename Arg2 = fusion::void_>
+            struct result
+            {
+                //  BOOST_MSVC #if branch here in map_erase_result non-
+                //  standard behavior. The return type should be void but
+                //  VC7.1 prefers to return iterator_of<C>. As a result,
+                //  VC7.1 complains of error C2562:
+                //  boost::phoenix::stl::erase::operator() 'void' function
+                //  returning a value. Oh well... :*
+
+                typedef
+                    boost::mpl::eval_if<
+                        boost::is_same<Arg1, typename iterator_of<C>::type>
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1400)
+                      , iterator_of<C>
+#else
+                      , boost::mpl::identity<void>
+#endif
+                      , size_type_of<C>
+                    >
+                map_erase_result;
+
+                typedef typename
+                    boost::mpl::eval_if<
+                        has_mapped_type<C>
+                      , map_erase_result
+                      , iterator_of<C>
+                    >::type
+                type;
+            };
+
+            template <typename C, typename Arg1>
+            typename result<C, Arg1>::type
+            operator()(C& c, Arg1 const& arg1) const
+            {
+                return c.erase(arg1);
+            }
+
+            template <typename C, typename Arg1, typename Arg2>
+            typename result<C, Arg1, Arg2>::type
+            operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
+            {
+                return c.erase(arg1, arg2);
+            }
+        };
+
+        struct front
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename const_qualified_reference_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.front();
+            }
+        };
+
+        struct get_allocator
+        {
+            template <typename C>
+            struct result
+            {
+        	    typedef typename allocator_type_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C const& c) const
+            {
+                return c.get_allocator();
+            }
+        };
+
+        struct insert
+        {
+            //  This mouthful can differentiate between the generic insert
+            //  functions (Container == deque, list, vector) and those
+            //  specific to the two map-types, std::map and std::multimap.
+            //
+            //  where C is a std::deque, std::list, std::vector:
+            //
+            //      1) iterator C::insert(iterator where, value_type value);
+            //      2) void C::insert(
+            //          iterator where, size_type count, value_type value);
+            //      3) template <typename Iter>
+            //         void C::insert(iterator where, Iter first, Iter last);
+            //
+            //  where M is a std::map and MM is a std::multimap:
+            //
+            //      4) pair<iterator, bool> M::insert(value_type const&);
+            //      5) iterator MM::insert(value_type const&);
+            //
+            //  where M is a std::map or std::multimap:
+            //
+            //      6) template <typename Iter>
+            //         void M::insert(Iter first, Iter last);
+
+            template <
+                typename C
+              , typename Arg1
+              , typename Arg2 = fusion::void_
+              , typename Arg3 = fusion::void_
+            >
+            class result
+            {
+                struct pair_iterator_bool
+                {
+                    typedef typename std::pair<typename C::iterator, bool> type;
+                };
+
+                typedef
+                    boost::mpl::eval_if<
+                        map_insert_returns_pair<C>
+                      , pair_iterator_bool
+                      , iterator_of<C>
+                    >
+                choice_1;
+
+                typedef
+                    boost::mpl::eval_if<
+                        boost::mpl::and_<
+                            boost::is_same<Arg3, fusion::void_>
+                          , boost::mpl::not_<boost::is_same<Arg1, Arg2> > >
+                      , iterator_of<C>
+                      , boost::mpl::identity<void>
+                    >
+                choice_2;
+
+            public:
+
+                typedef typename
+                    boost::mpl::eval_if<
+        		        boost::is_same<Arg2, fusion::void_>
+                      , choice_1
+                      , choice_2
+                    >::type
+                type;
+            };
+
+            template <typename C, typename Arg1>
+            typename result<C, Arg1>::type
+            operator()(C& c, Arg1 const& arg1) const
+            {
+        	    return c.insert(arg1);
+            }
+
+            template <typename C, typename Arg1, typename Arg2>
+            typename result<C, Arg1, Arg2>::type
+            operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
+            {
+                return c.insert(arg1, arg2);
+            }
+
+            template <typename C, typename Arg1, typename Arg2, typename Arg3>
+            typename result<C, Arg1, Arg2, Arg3>::type
+            operator()(
+                C& c, Arg1 const& arg1, Arg2 const& arg2, Arg3 const& arg3) const
+            {
+                return c.insert(arg1, arg2, arg3);
+            }
+        };
+
+        struct key_comp
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename key_compare_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C const& c) const
+            {
+                return c.key_comp();
+            }
+        };
+
+        struct max_size
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename size_type_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C const& c) const
+            {
+                return c.max_size();
+            }
+        };
+
+        struct pop_back
+        {
+            template <typename C>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C>
+            void operator()(C& c) const
+            {
+                return c.pop_back();
+            }
+        };
+
+        struct pop_front
+        {
+            template <typename C>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C>
+            void operator()(C& c) const
+            {
+                return c.pop_front();
+            }
+        };
+
+        struct push_back
+        {
+            template <typename C, typename Arg>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C, typename Arg>
+            void operator()(C& c, Arg const& data) const
+            {
+                return c.push_back(data);
+            }
+        };
+
+        struct push_front
+        {
+            template <typename C, typename Arg>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C, typename Arg>
+            void operator()(C& c, Arg const& data) const
+            {
+                return c.push_front(data);
+            }
+        };
+
+        struct rbegin
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename
+                    const_qualified_reverse_iterator_of<C>::type
+                type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.rbegin();
+            }
+        };
+
+        struct rend
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename
+                    const_qualified_reverse_iterator_of<C>::type
+                type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C& c) const
+            {
+                return c.rend();
+            }
+        };
+
+        struct reserve
+        {
+
+            template <typename C, typename Arg>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C, typename Arg>
+            void operator()(C& c, Arg const& count) const
+            {
+                return c.reserve(count);
+            }
+        };
+
+        struct resize
+        {
+            template <typename C, typename Arg1, typename Arg2 = fusion::void_>
+            struct result
+            {
+                typedef void type;
+            };
+
+            template <typename C, typename Arg1>
+            void operator()(C& c, Arg1 const& arg1) const
+            {
+                return c.resize(arg1);
+            }
+
+            template <typename C, typename Arg1, typename Arg2>
+            void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
+            {
+                return c.resize(arg1, arg2);
+            }
+        };
+
+        struct size
+        {
+            template <typename C>
+            struct result
+            {
+                typedef typename size_type_of<C>::type type;
+            };
+
+            template <typename C>
+            typename result<C>::type
+            operator()(C const& c) const
+            {
+                return c.size();
+            }
+        };
+
+    struct splice
+    {
+        template <
+            typename C
+          , typename Arg1
+          , typename Arg2
+          , typename Arg3 = fusion::void_
+          , typename Arg4 = fusion::void_
+        >
+        struct result
+        {
+            typedef void type;
+        };
+
+        template <typename C, typename Arg1, typename Arg2>
+        void operator()(C& c, Arg1 const& arg1, Arg2& arg2) const
+        {
+            c.splice(arg1, arg2);
+        }
+
+        template <
+            typename C
+          , typename Arg1
+          , typename Arg2
+          , typename Arg3
+        >
+        void operator()(
+            C& c
+          , Arg1 const& arg1
+          , Arg2& arg2
+          , Arg3 const& arg3
+        ) const
+        {
+            c.splice(arg1, arg2, arg3);
+        }
+
+        template <
+            typename C
+          , typename Arg1
+          , typename Arg2
+          , typename Arg3
+          , typename Arg4
+        >
+        void operator()(
+            C& c
+          , Arg1 const& arg1
+          , Arg2& arg2
+          , Arg3 const& arg3
+          , Arg4 const& arg4
+        ) const
+        {
+            c.splice(arg1, arg2, arg3, arg4);
+        }
+    };
+
+    struct value_comp
+    {
+        template <typename C>
+        struct result
+        {
+            typedef typename value_compare_of<C>::type type;
+        };
+
+        template <typename C>
+        typename result<C>::type
+        operator()(C const& c) const
+        {
+            return c.value_comp();
+        }
+    };
+
+} // namespace stl
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The lazy functions themselves.
+//
+///////////////////////////////////////////////////////////////////////////////
+function<stl::assign> const         assign = stl::assign();
+function<stl::at> const             at = stl::at();
+function<stl::back> const           back = stl::back();
+function<stl::begin> const          begin = stl::begin();
+function<stl::capacity> const       capacity = stl::capacity();
+function<stl::clear> const          clear = stl::clear();
+function<stl::empty> const          empty = stl::empty();
+function<stl::end> const            end = stl::end();
+function<stl::erase> const          erase = stl::erase();
+function<stl::front> const          front = stl::front();
+function<stl::get_allocator> const  get_allocator = stl::get_allocator();
+function<stl::insert> const         insert = stl::insert();
+function<stl::key_comp> const       key_comp = stl::key_comp();
+function<stl::max_size> const       max_size = stl::max_size();
+function<stl::pop_back> const       pop_back  = stl::pop_back();
+function<stl::pop_front> const      pop_front = stl::pop_front();
+function<stl::push_back> const      push_back  = stl::push_back();
+function<stl::push_front> const     push_front = stl::push_front();
+function<stl::rbegin> const         rbegin = stl::rbegin();
+function<stl::rend> const           rend = stl::rend();
+function<stl::reserve> const        reserve = stl::reserve();
+function<stl::resize> const         resize = stl::resize();
+function<stl::size> const           size = stl::size();
+function<stl::splice> const         splice = stl::splice();
+function<stl::value_comp> const     value_comp = stl::value_comp();
+
+}} // namespace boost::phoenix
+
+#endif // PHOENIX_STL_CONTAINERS_HPP
Added: trunk/boost/spirit/home/phoenix/stl/container/detail/container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/stl/container/detail/container.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,173 @@
+/*=============================================================================
+    Copyright (c) 2004 Angus Leeming
+    Copyright (c) 2004 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
+#define PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP
+
+#include <utility>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+namespace boost { namespace phoenix { namespace stl
+{
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Metafunctions "value_type_of", "key_type_of" etc.
+//
+//      These metafunctions define a typedef "type" that returns the nested
+//      type if it exists. If not then the typedef returns void.
+//
+//      For example, "value_type_of<std::vector<int> >::type" is "int" whilst
+//      "value_type_of<double>::type" is "void".
+//
+//      I use a macro to define structs "value_type_of" etc simply to cut
+//      down on the amount of code. The macro is #undef-ed immediately after
+//      its final use.
+//
+/////////////////////////////////////////////////////////////////c//////////////
+#define MEMBER_TYPE_OF(MEMBER_TYPE)                                             \
+    template <typename C>                                                       \
+    struct BOOST_PP_CAT(MEMBER_TYPE, _of)                                       \
+    {                                                                           \
+        typedef typename C::MEMBER_TYPE type;                                   \
+    }
+
+    MEMBER_TYPE_OF(allocator_type);
+    MEMBER_TYPE_OF(const_iterator);
+    MEMBER_TYPE_OF(const_reference);
+    MEMBER_TYPE_OF(const_reverse_iterator);
+    MEMBER_TYPE_OF(container_type);
+    MEMBER_TYPE_OF(data_type);
+    MEMBER_TYPE_OF(iterator);
+    MEMBER_TYPE_OF(key_compare);
+    MEMBER_TYPE_OF(key_type);
+    MEMBER_TYPE_OF(reference);
+    MEMBER_TYPE_OF(reverse_iterator);
+    MEMBER_TYPE_OF(size_type);
+    MEMBER_TYPE_OF(value_compare);
+    MEMBER_TYPE_OF(value_type);
+
+#undef MEMBER_TYPE_OF
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Const-Qualified types.
+//
+//      Many of the stl member functions have const and non-const
+//      overloaded versions that return distinct types. For example:
+//
+//          iterator begin();
+//          const_iterator begin() const;
+//
+//      The three class templates defined below,
+//      const_qualified_reference_of, const_qualified_iterator_of
+//      and const_qualified_reverse_iterator_of provide a means to extract
+//      this return type automatically.
+//
+///////////////////////////////////////////////////////////////////////////////
+    template <typename C>
+    struct const_qualified_reference_of
+    {
+        typedef typename
+            boost::mpl::eval_if<
+                boost::is_const<C>
+              , const_reference_of<C>
+              , reference_of<C>
+            >::type
+        type;
+    };
+
+    template <typename C>
+    struct const_qualified_iterator_of
+    {
+        typedef typename
+            boost::mpl::eval_if<
+                boost::is_const<C>
+              , const_iterator_of<C>
+              , iterator_of<C>
+            >::type
+        type;
+    };
+
+    template <typename C>
+    struct const_qualified_reverse_iterator_of
+    {
+        typedef typename
+            boost::mpl::eval_if<
+                boost::is_const<C>
+              , const_reverse_iterator_of<C>
+              , reverse_iterator_of<C>
+            >::type
+        type;
+    };
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  has_mapped_type<C>
+//
+//      Given a container C, determine if it is a map or multimap
+//      by checking if it has a member type named "mapped_type".
+//
+///////////////////////////////////////////////////////////////////////////////
+    namespace stl_impl
+    {
+        struct one { char a[1]; };
+        struct two { char a[2]; };
+
+        template <typename C>
+        one has_mapped_type(typename C::mapped_type(*)());
+
+        template <typename C>
+        two has_mapped_type(...);
+    }
+
+    template <typename C>
+    struct has_mapped_type
+        : boost::mpl::bool_<
+            sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one)
+        >
+    {};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  map_insert_returns_pair<C>
+//
+//      Distinguish a map from a multimap by checking the return type
+//      of its "insert" member function. A map returns a pair while
+//      a multimap returns an iterator.
+//
+///////////////////////////////////////////////////////////////////////////////
+    namespace stl_impl
+    {
+        //  Cool implementation of map_insert_returns_pair by Daniel Wallin.
+        //  Thanks Daniel!!! I owe you a Pizza!
+
+        template<class A, class B>
+        one map_insert_returns_pair_check(std::pair<A,B> const&);
+
+        template <typename T>
+        two map_insert_returns_pair_check(T const&);
+
+        template <typename C>
+        struct map_insert_returns_pair
+        {
+            static typename C::value_type const& get;
+            BOOST_STATIC_CONSTANT(int,
+                value = sizeof(
+                    map_insert_returns_pair_check(((C*)0)->insert(get))));
+            typedef boost::mpl::bool_<value == sizeof(one)> type;
+        };
+    }
+
+    template <typename C>
+    struct map_insert_returns_pair
+        : stl_impl::map_insert_returns_pair<C>::type {};
+
+}}} // namespace boost::phoenix::stl
+
+#endif // PHOENIX_STL_CONTAINER_TRAITS_HPP
Added: trunk/boost/spirit/home/phoenix/version.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/phoenix/version.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+/*=============================================================================
+    Copyright (c) 2005-2008 Hartmut Kaiser
+    Copyright (c) 2005-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef PHOENIX_VERSION_HPP
+#define PHOENIX_VERSION_HPP
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  This is the version of the library
+//
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_PHOENIX_VERSION   0x2000    // 2.0.0
+
+#endif
Added: trunk/boost/spirit/home/qi.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,22 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_QI_MARCH_04_2007_0852PM)
+#define BOOST_SPIRIT_QI_MARCH_04_2007_0852PM
+
+#include <boost/spirit/home/qi/char.hpp>
+#include <boost/spirit/home/qi/string.hpp>
+#include <boost/spirit/home/qi/numeric.hpp>
+#include <boost/spirit/home/qi/operator.hpp>
+#include <boost/spirit/home/qi/auxiliary.hpp>
+#include <boost/spirit/home/qi/action.hpp>
+#include <boost/spirit/home/qi/nonterminal.hpp>
+#include <boost/spirit/home/qi/directive.hpp>
+#include <boost/spirit/home/qi/parse.hpp>
+#include <boost/spirit/home/qi/debug.hpp>
+#include <boost/spirit/home/qi/what.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/action.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/action.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,13 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(SPIRIT_ACTION_JAN_07_2007_1233PM)
+#define SPIRIT_ACTION_JAN_07_2007_1233PM
+
+#include <boost/spirit/home/qi/action/action.hpp>
+#include <boost/spirit/home/qi/action/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/action/action.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/action/action.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ACTION_JAN_07_2007_1128AM)
+#define SPIRIT_ACTION_JAN_07_2007_1128AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct action
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+          : traits::attribute_of<
+                qi::domain
+              , typename result_of::left<Component>::type
+              , Context
+              , Iterator
+            >
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr_)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            director;
+
+            typedef typename
+                attribute<Component, Context, Iterator>::type
+            attr_type;
+
+            // create an attribute if one is not supplied
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>
+              , typename remove_const<attr_type>::type
+              , Attribute&>::type
+            attr = spirit::detail::make_value<attr_type>::call(attr_);
+
+            if (director::parse(
+                spirit::left(component), first, last, context, skipper, attr))
+            {
+                // call the function, passing the attribute, the context
+                // and a bool flag that the client can set to false to
+                // fail parsing.
+                bool pass = true;
+                spirit::right(component)(
+                    spirit::detail::pass_value<attr_type>::call(attr), context, pass);
+                return pass;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            director;
+
+            return director::what(spirit::left(component));
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/action/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/action/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,58 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_07_2007_1100AM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_07_2007_1100AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    struct action;
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // action meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct action_meta_grammar : 
+        meta_grammar::binary_rule<
+            qi::domain, proto::tag::subscript, action
+          , main_meta_grammar, proto::when<proto::_, proto::_arg>
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, action_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, action_meta_grammar> >::type>
+      : mpl::identity<action_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,18 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_AUXILIARY_FEB_03_2007_0355PM)
+#define BOOST_SPIRIT_STRING_FEB_03_2007_0355PM
+
+#include <boost/spirit/home/qi/auxiliary/none.hpp>
+#include <boost/spirit/home/qi/auxiliary/eps.hpp>
+#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
+#include <boost/spirit/home/qi/auxiliary/functor.hpp>
+#include <boost/spirit/home/qi/auxiliary/functor_director.hpp>
+#include <boost/spirit/home/qi/auxiliary/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/eps.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/eps.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,76 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_EPS_MARCH_23_2007_0454PM)
+#define BOOST_SPIRIT_EPS_MARCH_23_2007_0454PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/at.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct eps_parser
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& /*component*/
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            qi::skip(first, last, skipper);
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "eps";
+        }
+    };
+
+    struct semantic_predicate
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            qi::skip(first, last, skipper);
+            return fusion::at_c<0>(component.elements)(unused, context);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "semantic-predicate";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/functor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/functor.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,210 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_FUNCTOR_APR_01_2007_0817AM)
+#define BOOST_SPIRIT_FUNCTOR_APR_01_2007_0817AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
+#include <boost/spirit/home/support/auxiliary/meta_function_holder.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit 
+{ 
+    namespace qi
+    {
+        template <typename Functor, typename ParameterMF = Functor>
+        class functor_parser;
+    }
+    
+    namespace result_of
+    {
+        template <typename Functor>
+        struct as_parser
+        {
+            typedef qi::functor_parser<Functor> type;
+        };
+
+        template <typename ParameterMF, typename Functor>
+        struct as_parser_mf
+        {
+            typedef qi::functor_parser<Functor, ParameterMF> type;
+        };
+    }
+        
+}}  // boost::spirit
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This struct may be used as a base class for a user defined functor
+    ///////////////////////////////////////////////////////////////////////////
+    struct functor_base
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  The return value of a qi functor is always bool
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Attribute, typename Iterator, typename Context>
+        struct result
+        {
+            typedef bool type;
+        };
+
+// FIXME: It will be possible to specify the return value as a typedef, but for 
+//        that Phoenix will have to be fixed.
+//         typedef bool result_type;
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The expected parameter type of a functor has to be defined using a
+        //  embedded apply metafunction. Normally this will be overloaded by 
+        //  the derived class, but the default is unused type.
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator, typename Context>
+        struct apply
+        {
+            typedef spirit::unused_type type;
+        };
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Functor, typename ParameterMF>
+    class functor_parser
+      : public proto::extends<
+            typename make_functor_holder<
+                functor_parser<Functor, ParameterMF> const*, 
+                functor_parser<Functor, ParameterMF>
+            >::type,
+            functor_parser<Functor, ParameterMF>
+        >
+    {
+    private:
+        typedef functor_parser<Functor, ParameterMF> self_type;
+        typedef typename
+            make_functor_holder<self_type const*, self_type>::type
+        functor_tag;
+        typedef proto::extends<functor_tag, self_type> base_type;
+
+    public:
+        template <typename Iterator, typename Context>
+        struct result 
+          : mpl::apply<ParameterMF, Iterator, Context>
+        {};
+
+    private:
+        // parse function just delegates to the functor supplied function
+        template <typename Iterator, typename Context, typename Attribute>
+        bool
+        parse (Iterator& first, Iterator const& last, Context& ctx,
+            Attribute& attr_) const
+        {
+            // create an attribute if none is supplied
+            typedef typename result<Iterator, Context>::type attr_type;
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>,
+                attr_type,
+                Attribute&
+            >::type
+            attr = spirit::detail::make_value<attr_type>::call(attr_);
+
+            return functor(attr, ctx, first, last);
+        }
+
+        friend struct functor_director;
+
+    public:
+        explicit functor_parser()
+          : base_type(make_tag())
+        {
+        }
+
+        functor_parser(Functor const& functor_)
+          : base_type(make_tag()), functor(functor_)
+        {
+        }
+
+        functor_parser(Functor const& functor_, ParameterMF const& mf)
+          : base_type(make_tag()), functor(functor_), mf_(mf)
+        {
+        }
+
+    private:
+        functor_tag make_tag() const
+        {
+            functor_tag xpr = {{ this }};
+            return xpr;
+        }
+        
+        Functor functor;
+        meta_function_holder<Functor, ParameterMF> mf_;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  The as_parser generator function may be used to create a functor 
+    //  parser from a function object (some callable item).
+    //  The supplied functor needs to expose
+    // 
+    //    - an embedded result meta function: 
+    //
+    //          template <typename Attribute, typename Iterator, typename Context>
+    //          struct result
+    //          {
+    //              typedef bool type;
+    //          };
+    //
+    //      which declares 'bool' as the result type of the defined function
+    //      operator and
+    //
+    //    - an embedded apply meta function:
+    //
+    //          template <typename Iterator, typename Context>
+    //          struct apply
+    //          {
+    //              typedef unspecified type;
+    //          };
+    //
+    //      which declares the given type as the expected parameter type for 
+    //      the generator to create.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Functor>
+    inline typename result_of::as_parser<Functor>::type
+    as_parser(Functor const& func)
+    {
+        return functor_parser<Functor>(func);
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  The as_parser_mf generator function is equivalent to the function
+    //  as_parser above except that the user has explicitly to specify a
+    //  type exposing an embedded apply meta function declaring the expected
+    //  parameter type for the generator to create.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ParameterMF, typename Functor>
+    inline typename result_of::as_parser_mf<ParameterMF, Functor>::type
+    as_parser_mf(Functor const& func, ParameterMF const& mf)
+    {
+        return functor_parser<Functor, ParameterMF>(func, mf);
+    }
+    
+    template <typename ParameterMF, typename Functor>
+    inline typename result_of::as_parser_mf<ParameterMF, Functor>::type
+    as_parser_mf(Functor const& func)
+    {
+        return functor_parser<Functor, ParameterMF>(func, ParameterMF());
+    }
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/functor_director.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/functor_director.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,52 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_FUNCTOR_DIRECTOR_APR_01_2007_0847AM)
+#define BOOST_SPIRIT_FUNCTOR_DIRECTOR_APR_01_2007_0847AM
+
+#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    // this is the director for all functor parsers
+    struct functor_director
+    {
+        // return value of the parser
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type::functor_type
+            functor_type;
+
+            typedef typename
+                functor_type::template result<Iterator, Context>::type
+            type;
+        };
+
+        // parse functionality, delegates back to the corresponding functor
+        template <typename Component, typename Iterator, typename Context,
+            typename Skipper, typename Attribute>
+        static bool parse(Component const& component,
+            Iterator& first, Iterator const& last, Context& context,
+            Skipper const& skipper, Attribute& attr)
+        {
+            // main entry point, just forward to the functor parse function
+            qi::skip(first, last, skipper);         // always do a pre-skip
+            return subject(component).held->parse(first, last, context, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "functor";
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/lazy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/lazy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,106 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM)
+#define BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct lazy_parser
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<subject_type(unused_type, Context)>::type
+                >::type
+            expr_type;
+
+            typedef typename
+                result_of::as_component<qi::domain, expr_type>::type
+            component_type;
+
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, component_type, Context, Iterator>::type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<subject_type(unused_type, Context)>::type
+                >::type
+            expr_type;
+
+            typedef typename
+                result_of::as_component<qi::domain, expr_type>::type
+            component_type;
+
+            component_type subject
+                = spirit::as_component(
+                    qi::domain(), fusion::at_c<0>(component.elements)(unused, context));
+
+            return component_type::director::
+                parse(subject, first, last, context, skipper, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            //~ typedef typename
+                //~ result_of::subject<Component>::type
+            //~ subject_type;
+
+            //~ typedef typename
+                //~ remove_reference<
+                    //~ typename boost::result_of<subject_type(unused_type, unused_type)>::type
+                //~ >::type
+            //~ expr_type;
+
+            //~ typedef typename
+                //~ result_of::as_component<qi::domain, expr_type>::type
+            //~ component_type;
+
+            //~ component_type subject
+                //~ = spirit::as_component(
+                    //~ qi::domain(), fusion::at_c<0>(component.elements)(unused, unused));
+
+            std::string result = "lazy[";
+            //~ result += component_type::director::what(subject);
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,82 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_MARCH_23_2007_0537PM)
+#define BOOST_SPIRIT_META_GRAMMAR_MARCH_23_2007_0537PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit
+{
+    template <typename T, typename Functor>
+    struct functor_holder;
+}}
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct none;
+    struct eps_parser;
+    struct semantic_predicate;
+    struct lazy_parser;
+    struct functor_director;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // auxiliary parsers meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+
+    // none, eps and eps(f)
+    struct auxiliary_meta_grammar
+      : proto::or_<
+            meta_grammar::empty_terminal_rule<
+                qi::domain, tag::none, none>
+          , meta_grammar::empty_terminal_rule<
+                qi::domain, tag::eps, eps_parser>
+          , meta_grammar::function1_rule<
+                qi::domain, tag::eps, semantic_predicate>
+          , meta_grammar::function1_rule<
+                qi::domain, tag::lazy, lazy_parser>
+          , meta_grammar::terminal_rule<
+                qi::domain
+              , functor_holder<proto::_, proto::_>
+              , functor_director
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, auxiliary_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, auxiliary_meta_grammar> >::type>
+      : mpl::identity<auxiliary_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/auxiliary/none.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/none.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,46 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NONE_MARCH_23_2007_0454PM)
+#define BOOST_SPIRIT_NONE_MARCH_23_2007_0454PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct none
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& /*component*/
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            qi::skip(first, last, skipper);
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "none";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/binary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/binary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_BINARY_MAY_08_2007_0906AM)
+#define BOOST_SPIRIT_BINARY_MAY_08_2007_0906AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/binary/binary.hpp>
+#include <boost/spirit/home/qi/binary/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/binary/binary.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/binary/binary.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,194 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_BINARY_MAY_08_2007_0808AM)
+#define BOOST_SPIRIT_BINARY_MAY_08_2007_0808AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/integer/endian.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    namespace detail
+    {
+        template <int bits>
+        struct integer
+        {
+#ifdef BOOST_HAS_LONG_LONG
+            BOOST_MPL_ASSERT_MSG(
+                bits == 8 || bits == 16 || bits == 32 || bits == 64,
+                not_supported_binary_size, ());
+#else
+            BOOST_MPL_ASSERT_MSG(
+                bits == 8 || bits == 16 || bits == 32,
+                not_supported_binary_size, ());
+#endif
+        };
+
+        template <>
+        struct integer<8>
+        {
+            typedef uint_least8_t type;
+        };
+
+        template <>
+        struct integer<16>
+        {
+            typedef uint_least16_t type;
+        };
+
+        template <>
+        struct integer<32>
+        {
+            typedef uint_least32_t type;
+        };
+
+#ifdef BOOST_HAS_LONG_LONG
+        template <>
+        struct integer<64>
+        {
+            typedef uint_least64_t type;
+        };
+#endif
+
+        ///////////////////////////////////////////////////////////////////////
+        template <boost::integer::endianness bits>
+        struct what;
+
+        template <>
+        struct what<boost::integer::native>
+        {
+            static std::string is()
+            {
+                return "native-endian binary";
+            }
+        };
+
+        template <>
+        struct what<boost::integer::little>
+        {
+            static char const* is()
+            {
+                return "little-endian binary";
+            }
+        };
+
+        template <>
+        struct what<boost::integer::big>
+        {
+            static char const* is()
+            {
+                return "big-endian binary";
+            }
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <integer::endianness endian, int bits>
+    struct any_binary_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef boost::integer::endian<
+                endian, typename qi::detail::integer<bits>::type, bits
+            > type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const&
+          , Iterator& first, Iterator const& last
+          , Context&, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+
+            typename
+                traits::attribute_of<
+                    qi::domain, Component, Context, Iterator>::type
+            attr_;
+            unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
+
+            Iterator it = first;
+            for (unsigned int i = 0; i < sizeof(attr_); ++i)
+            {
+                if (it == last)
+                    return false;
+                *bytes++ = *it++;
+            }
+
+            first = it;
+            detail::assign_to(attr_, attr);
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return qi::detail::what<endian>::is();
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <integer::endianness endian, int bits>
+    struct binary_lit_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context&, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+
+            boost::integer::endian<
+                endian, typename qi::detail::integer<bits>::type, bits
+            > attr_ (fusion::at_c<0>(component.elements));
+            unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
+
+            Iterator it = first;
+            for (unsigned int i = 0; i < sizeof(attr_); ++i)
+            {
+                if (it == last || *bytes++ != *it++)
+                    return false;
+            }
+
+            first = it;
+            detail::assign_to(attr_, attr);
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return qi::detail::what<endian>::is();
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/binary/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/binary/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,259 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_MAY_08_2007_0824AM)
+#define BOOST_SPIRIT_META_GRAMMAR_MAY_08_2007_0824AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/support/detail/integer/endian.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    template <integer::endianness endian, int bits>
+    struct any_binary_director;
+    
+    template <integer::endianness endian, int bits>
+    struct binary_lit_director;
+
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of an integer based binary literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_literal_bin_director
+    {
+        typedef binary_lit_director<
+            boost::integer::native, sizeof(T)*CHAR_BIT
+        > type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a binary tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_binary_director;
+
+    // native endian binaries
+    template <>
+    struct extract_binary_director<tag::byte>    
+    {
+        typedef any_binary_director<boost::integer::native, 8> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::word>    
+    {
+        typedef any_binary_director<boost::integer::native, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::dword>    
+    {
+        typedef any_binary_director<boost::integer::native, 32> type;
+    };
+
+    // big endian binaries
+    template <>
+    struct extract_binary_director<tag::big_word>    
+    {
+        typedef any_binary_director<boost::integer::big, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::big_dword>    
+    {
+        typedef any_binary_director<boost::integer::big, 32> type;
+    };
+
+    // little endian binaries
+    template <>
+    struct extract_binary_director<tag::little_word>    
+    {
+        typedef any_binary_director<boost::integer::little, 16> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::little_dword>    
+    {
+        typedef any_binary_director<boost::integer::little, 32> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <>
+    struct extract_binary_director<tag::qword>    
+    {
+        typedef any_binary_director<boost::integer::native, 64> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::big_qword>    
+    {
+        typedef any_binary_director<boost::integer::big, 64> type;
+    };
+
+    template <>
+    struct extract_binary_director<tag::little_qword>    
+    {
+        typedef any_binary_director<boost::integer::little, 64> type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a binary literal tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_binary_lit_director;
+
+    // native endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::byte, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 8> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::word, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 32> type;
+    };
+
+    // big endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_word, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 32> type;
+    };
+
+    // little endian binaries
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_word, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 16> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_dword, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 32> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <typename T>
+    struct extract_binary_lit_director<tag::qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::native, 64> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::big_qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::big, 64> type;
+    };
+
+    template <typename T>
+    struct extract_binary_lit_director<tag::little_qword, T>    
+    {
+        typedef binary_lit_director<boost::integer::little, 64> type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // binary meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    // literals: 10, 10L, 10LL
+    struct int_binary_meta_grammar
+      : meta_grammar::compose_empty<
+            proto::if_<
+                is_int_lit_tag<proto::_arg, qi::domain>()
+            >,
+            qi::domain,
+            mpl::identity<extract_literal_bin_director<mpl::_> >
+        >
+    {
+    };
+
+    struct binary_meta_grammar  
+      : proto::or_<
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_binary_tag<proto::_arg, qi::domain>()
+                >,
+                qi::domain, 
+                mpl::identity<extract_binary_director<mpl::_> > 
+            >,
+            meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_binary_tag<proto::_arg, qi::domain>()
+                    >,
+                    int_binary_meta_grammar
+                >,
+                qi::domain,
+                mpl::identity<extract_binary_lit_director<mpl::_, mpl::_> >
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Qi meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, binary_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, binary_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<binary_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,15 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_CHAR_FEB_02_2007_0921AM)
+#define BOOST_SPIRIT_CHAR_FEB_02_2007_0921AM
+
+#include <boost/spirit/home/qi/char/char_parser.hpp>
+#include <boost/spirit/home/qi/char/char.hpp>
+#include <boost/spirit/home/qi/char/char_class.hpp>
+#include <boost/spirit/home/qi/char/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/char/char.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/char.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,295 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_CHAR_APR_16_2006_1051AM)
+#define BOOST_SPIRIT_CHAR_APR_16_2006_1051AM
+
+#include <boost/spirit/home/qi/char/char_parser.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/detail/to_narrow.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // parse any character
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_char : char_parser<any_char<Char>, Char>
+    {
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const&, CharParam, Context&)
+        {
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "any-char";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // parse a single character
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct literal_char : char_parser<literal_char<Char>, Char>
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;   // literal parsers have no attribute
+        };
+
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context&)
+        {
+            return fusion::at_c<0>(component.elements) == ch;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("'")
+                + spirit::detail::to_narrow_char(
+                    fusion::at_c<0>(component.elements)) 
+                + '\'';
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // parse a lazy character
+    ///////////////////////////////////////////////////////////////////////////
+    struct lazy_char : char_parser<lazy_char>
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<subject_type(unused_type, Context)>::type
+                >::type
+            type;
+        };
+
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context& context)
+        {
+            return fusion::at_c<0>(component.elements)(unused, context) == ch;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "char";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // parse a character range
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct char_range : char_parser<char_range<Char>, Char>
+    {
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context&)
+        {
+            return
+                !(ch < fusion::at_c<0>(component.elements)) &&
+                !(fusion::at_c<1>(component.elements) < ch);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result;
+            result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
+            result += "...";
+            result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
+            return result;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // parse a lazy character range
+    ///////////////////////////////////////////////////////////////////////////
+    struct lazy_char_range : char_parser<lazy_char_range>
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<subject_type(unused_type, Context)>::type
+                >::type
+            type;
+        };
+
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context& context)
+        {
+            return
+                !(ch < fusion::at_c<0>(component.elements)(unused, context)) &&
+                !(fusion::at_c<1>(component.elements)(unused, context) < ch);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "char-range";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case literal_char version
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct no_case_literal_char : char_parser<no_case_literal_char<Char>, Char>
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;   // literal parsers have no attribute
+        };
+
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context&)
+        {
+            return fusion::at_c<0>(component.elements) == ch
+                || fusion::at_c<1>(component.elements) == ch
+            ;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result;
+            result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
+            result += " or ";
+            result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
+            return result;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case char_range version
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct no_case_char_range : char_parser<no_case_char_range<Char>, Char>
+    {
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context&)
+        {
+            return
+                (!(ch < fusion::at_c<0>(component.elements)) &&
+                 !(fusion::at_c<1>(component.elements) < ch))
+            ||  (!(ch < fusion::at_c<2>(component.elements)) &&
+                 !(fusion::at_c<3>(component.elements) < ch))
+            ;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result;
+            result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
+            result += "...";
+            result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
+            result += " or ";
+            result += std::string("'") + fusion::at_c<2>(component.elements) + '\'';
+            result += "...";
+            result += std::string("'") + fusion::at_c<3>(component.elements) + '\'';
+            return result;
+        }
+    };
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case_literal_char generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Elements, typename Modifier, typename Char
+    >
+    struct make_modified_component<
+        Domain, qi::literal_char<Char>, Elements, Modifier
+      , typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
+        >::type
+    >
+    {
+        typedef fusion::vector<Char, Char> vector_type;
+        typedef
+            component<qi::domain, qi::no_case_literal_char<Char>, vector_type>
+        type;
+
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+
+            Char ch = fusion::at_c<0>(elements);
+            vector_type v(
+                char_set::tolower(ch)
+              , char_set::toupper(ch)
+            );
+            return type(v);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case_char_range generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Elements, typename Modifier, typename Char
+    >
+    struct make_modified_component<
+        Domain, qi::char_range<Char>, Elements, Modifier
+      , typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
+        >::type
+    >
+    {
+        typedef fusion::vector<Char, Char, Char, Char> vector_type;
+        typedef
+            component<qi::domain, qi::no_case_char_range<Char>, vector_type>
+        type;
+
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+
+            Char first = fusion::at_c<0>(elements);
+            Char last = fusion::at_c<1>(elements);
+            vector_type v(
+                char_set::tolower(first)
+              , char_set::tolower(last)
+              , char_set::toupper(first)
+              , char_set::toupper(last)
+            );
+            return type(v);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/char_class.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/char_class.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,93 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM)
+#define BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM
+
+#include <boost/spirit/home/qi/char/char_parser.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/spirit/home/support/standard.hpp>
+#include <boost/spirit/home/support/standard_wide.hpp>
+#include <boost/fusion/include/cons.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // generic isxxx parser (for alnum, alpha, graph, etc.)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct char_class
+      : char_parser<char_class<Tag>, typename Tag::char_set::char_type>
+    {
+        typedef typename Tag::char_set char_set;
+        typedef typename Tag::char_class char_class_;
+
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const&, CharParam ch, Context&)
+        {
+            using spirit::char_class::classify;
+            return classify<char_set>::is(char_class_(), ch);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            typedef spirit::char_class::what<char_set> what_;
+            return what_::is(char_class_());
+        }
+    };
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case char_class conversions
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        using spirit::char_class::key;
+        using spirit::char_class::lower_case_tag;
+        using spirit::char_class::upper_case_tag;
+        using spirit::char_class::tag::alpha;
+
+        template <typename Tag>
+        struct make_no_case_char_class :
+            mpl::identity<qi::char_class<Tag> > {};
+
+        template <typename CharSet>
+        struct make_no_case_char_class<lower_case_tag<CharSet> >
+          : mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
+
+        template <typename CharSet>
+        struct make_no_case_char_class<upper_case_tag<CharSet> >
+          : mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
+    }
+
+    template <
+        typename Domain, typename Elements, typename Modifier, typename Tag
+    >
+    struct make_modified_component<
+        Domain, qi::char_class<Tag>, Elements, Modifier
+      , typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
+        >::type
+    >
+    {
+        typedef typename detail::make_no_case_char_class<Tag>::type director;
+        typedef component<qi::domain, director, fusion::nil> type;
+
+        static type
+        call(Elements const&)
+        {
+            return type(fusion::nil());
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/char_parser.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/char_parser.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,82 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM)
+#define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM
+
+#include <string>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/at.hpp>
+
+#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Derived, typename Char = unused_type>
+    struct char_parser
+    {
+        typedef Char char_type;
+
+        // if Char is unused_type, Derived must supply its own attribute metafunction
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef Char type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+
+            if (first != last && Derived::test(component, *first, context))
+            {
+                qi::detail::assign_to(*first, attr);
+                ++first;
+                return true;
+            }
+            return false;
+        }
+
+        // char_parser subclasses are required to
+        // implement test:
+
+        template <typename Component, typename CharParam, typename Context>
+        bool test(Component const& component, CharParam ch, Context& context);
+    };
+
+    template <typename Positive>
+    struct negated_char_parser :
+        char_parser<
+            negated_char_parser<Positive>, typename Positive::director::char_type
+        >
+    {
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context& context)
+        {
+            return !Positive::director::test(
+                fusion::at_c<0>(component.elements), ch, context);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("not ")
+                + Positive::director::what(fusion::at_c<0>(component.elements));
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/detail/range.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/detail/range.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,35 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM)
+#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  A closed range (first, last)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct range
+    {
+        typedef T value_type;
+
+        range()
+            : first(), last()
+        {
+        }
+
+        range(T first, T last)
+            : first(first), last(last)
+        {
+        }
+
+        T first;
+        T last;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/detail/range_functions.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/detail/range_functions.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,94 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
+#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
+
+#include <boost/integer_traits.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Range>
+    inline bool
+    is_valid(Range const& range)
+    {
+        // test for valid ranges
+        return range.first <= range.last;
+    }
+
+    template <typename Range>
+    inline bool
+    includes(Range const& range, Range const& other)
+    {
+        // see if two ranges intersect
+        return (range.first <= other.first) && (range.last >= other.last);
+    }
+
+    template <typename Range>
+    inline bool
+    includes(Range const& range, typename Range::value_type val)
+    {
+        // see if val is in range
+        return (range.first <= val) && (range.last >= val);
+    }
+
+    template <typename Range>
+    inline bool
+    can_merge(Range const& range, Range const& other)
+    {
+        // see if a 'range' overlaps, or is adjacent to
+        // another range 'other', so we can merge them
+
+        typedef typename Range::value_type value_type;
+        typedef integer_traits<value_type> integer_traits;
+
+        value_type decr_first =
+            range.first == integer_traits::const_min
+            ? range.first : range.first-1;
+
+        value_type incr_last =
+            range.last == integer_traits::const_max
+            ? range.last : range.last+1;
+
+        return (decr_first <= other.last) && (incr_last >= other.first);
+    }
+
+    template <typename Range>
+    inline void
+    merge(Range& result, Range const& other)
+    {
+        // merge two ranges
+        if (result.first > other.first)
+            result.first = other.first;
+        if (result.last < other.last)
+            result.last = other.last;
+    }
+
+    template <typename Range>
+    struct range_compare
+    {
+        // compare functor with a value or another range
+
+        typedef typename Range::value_type value_type;
+
+        bool operator()(Range const& x, const value_type y) const
+        {
+            return x.first < y;
+        }
+
+        bool operator()(value_type const x, Range const& y) const
+        {
+            return x < y.first;
+        }
+
+        bool operator()(Range const& x, Range const& y) const
+        {
+            return x.first < y.first;
+        }
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/detail/range_run.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/detail/range_run.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,52 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM)
+#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
+
+#include <boost/spirit/home/qi/char/detail/range.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  range_run
+    //
+    //      An implementation of a sparse bit (boolean) set. The set uses
+    //      a sorted vector of disjoint ranges. This class implements the
+    //      bare minimum essentials from which the full range of set
+    //      operators can be implemented. The set is constructed from
+    //      ranges. Internally, adjacent or overlapping ranges are
+    //      coalesced.
+    //
+    //      range_runs are very space-economical in situations where there
+    //      are lots of ranges and a few individual disjoint values.
+    //      Searching is O(log n) where n is the number of ranges.
+    //
+    //      { Low level interface }
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    class range_run
+    {
+    public:
+
+        typedef range<Char> range_type;
+        typedef std::vector<range_type> storage_type;
+
+        void swap(range_run& other);
+        bool test(Char v) const;
+        void set(range_type const& range);
+        void clear(range_type const& range);
+        void clear();
+
+    private:
+
+        storage_type run;
+    };
+}}}}
+
+#include <boost/spirit/home/qi/char/detail/range_run_impl.hpp>
+#endif
Added: trunk/boost/spirit/home/qi/char/detail/range_run_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/detail/range_run_impl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,181 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM)
+#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
+
+#include <boost/spirit/home/qi/char/detail/range_functions.hpp>
+#include <boost/assert.hpp>
+#include <boost/integer_traits.hpp>
+#include <algorithm>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    namespace detail
+    {
+        template <typename Run, typename Iterator, typename Range>
+        inline bool
+        try_merge(Run& run, Iterator iter, Range const& range)
+        {
+            // if *iter intersects with, or is adjacent to, 'range'...
+            if (can_merge(*iter, range))
+            {
+                typedef typename Range::value_type value_type;
+                typedef integer_traits<value_type> integer_traits;
+
+                // merge range and *iter
+                merge(*iter, range);
+
+                // collapse all subsequent ranges that can merge with *iter
+                Iterator i;
+                value_type last =
+                    iter->last == integer_traits::const_max
+                    ? iter->last : iter->last+1;
+
+                for (i = iter+1; i != run.end() && last >= i->first; ++i)
+                {
+                    iter->last = i->last;
+                }
+                // erase all ranges that were collapsed
+                run.erase(iter+1, i);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    template <typename Char>
+    inline bool
+    range_run<Char>::test(Char val) const
+    {
+        if (run.empty())
+            return false;
+
+        // search the ranges for one that potentially includes val
+        typename storage_type::const_iterator iter =
+            std::upper_bound(
+                run.begin(), run.end(), val,
+                range_compare<range_type>()
+            );
+
+        // return true if *(iter-1) includes val
+        return iter != run.begin() && includes(*(--iter), val);
+    }
+
+    template <typename Char>
+    inline void
+    range_run<Char>::swap(range_run& other)
+    {
+        run.swap(other.run);
+    }
+
+    template <typename Char>
+    void
+    range_run<Char>::set(range_type const& range)
+    {
+        BOOST_ASSERT(is_valid(range));
+        if (run.empty())
+        {
+            // the vector is empty, insert 'range'
+            run.push_back(range);
+            return;
+        }
+
+        // search the ranges for one that potentially includes 'range'
+        typename storage_type::iterator iter =
+            std::upper_bound(
+                run.begin(), run.end(), range,
+                range_compare<range_type>()
+            );
+
+        if (iter != run.begin())
+        {
+            // if *(iter-1) includes 'range', return early
+            if (includes(*(iter-1), range))
+            {
+                return;
+            }
+
+            // if *(iter-1) can merge with 'range', merge them and return
+            if (detail::try_merge(run, iter-1, range))
+            {
+                return;
+            }
+        }
+
+        // if *iter can merge with with 'range', merge them
+        if (iter == run.end() || !detail::try_merge(run, iter, range))
+        {
+            // no overlap, insert 'range'
+            run.insert(iter, range);
+        }
+    }
+
+    template <typename Char>
+    void
+    range_run<Char>::clear(range_type const& range)
+    {
+        BOOST_ASSERT(is_valid(range));
+        if (!run.empty())
+        {
+            // search the ranges for one that potentially includes 'range'
+            typename storage_type::iterator iter =
+                std::upper_bound(
+                    run.begin(), run.end(), range,
+                    range_compare<range_type>()
+                );
+
+            typename storage_type::iterator left_iter;
+
+            // if *(iter-1) includes the 'range.first',
+            if ((iter != run.begin()) &&
+                includes(*(left_iter = (iter-1)), range.first))
+            {
+                // if the 'range' is in the middle,
+                if (left_iter->last > range.last)
+                {
+                    // break it apart into two ranges (punch a hole)
+                    Char save_last = left_iter->last;
+                    left_iter->last = range.first-1;
+                    run.insert(iter, range_type(range.last+1, save_last));
+                    return;
+                }
+                else // if it is not in the middle,
+                {
+                    // truncate it (clip its right)
+                    left_iter->last = range.first-1;
+                }
+            }
+
+            // position i to the first range that 'range'
+            // does not intersect with
+            typename storage_type::iterator i = iter;
+            while (i != run.end() && includes(range, *i))
+            {
+                i++;
+            }
+
+            // if *i includes 'range.last', truncate it (clip its left)
+            if (i != run.end() && includes(*i, range.last))
+            {
+                i->first = range.last+1;
+            }
+
+            // cleanup... erase all subsequent ranges that the
+            // 'range' includes
+            run.erase(iter, i);
+        }
+    }
+
+    template <typename Char>
+    inline void
+    range_run<Char>::clear()
+    {
+        run.clear();
+    }
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/char/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,272 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct any_char;
+
+    template <typename Char>
+    struct literal_char;
+
+    struct lazy_char;
+
+    template <typename Char>
+    struct char_range;
+
+    struct lazy_char_range;
+
+    template <typename Positive>
+    struct negated_char_parser;
+
+    template <typename Tag>
+    struct char_class;
+
+    ///////////////////////////////////////////////////////////////////////////
+    struct char_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  get the director of an any_char
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_any_char_director;
+
+    template <>
+    struct extract_any_char_director<tag::char_>
+    {
+        typedef any_char<char> type;
+    };
+
+    template <>
+    struct extract_any_char_director<tag::wchar>
+    {
+        typedef any_char<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a character literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_literal_char_director;
+
+    template <typename T>
+    struct extract_literal_char_director<tag::char_, T>
+    {
+        typedef literal_char<T> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::wchar, T>
+    {
+        typedef literal_char<wchar_t> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::lit, T>
+    {
+        typedef literal_char<T> type;
+    };
+
+    template <typename T>
+    struct extract_literal_char_director<tag::wlit, T>
+    {
+        typedef literal_char<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a character range type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename T>
+    struct extract_char_range_director;
+
+    template <typename T>
+    struct extract_char_range_director<tag::char_, T>
+    {
+        typedef char_range<T> type;
+    };
+
+    template <typename T>
+    struct extract_char_range_director<tag::wchar, T>
+    {
+        typedef char_range<wchar_t> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // char parser meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+
+    // literals: 'x', L'x'
+    struct basic_char_literal_meta_grammar
+      : proto::or_<
+            proto::terminal<char>
+          , proto::terminal<wchar_t>
+        >
+    {
+    };
+
+    // literals: 'x', L'x'
+    struct char_literal_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                qi::domain, char, literal_char<char>
+            >
+          , meta_grammar::terminal_rule<
+                qi::domain, wchar_t, literal_char<wchar_t>
+            >
+        >
+    {
+    };
+
+    // char_, char_('x'), char_(f), char_('x', 'z'),
+    // char_(L'x'), char_(L'x', L'z'),
+    // wchar, wchar('x'), wchar('x', 'z'),
+    // wchar(L'x'), wchar(L'x', L'z')
+    // [w]lit('x'), [w]lit(L'x')
+    struct char_meta_grammar1
+      : proto::or_<
+            // char_, wchar --> any_char
+            meta_grammar::compose_empty<
+                proto::if_<
+                    is_char_tag<proto::_arg, qi::domain>()
+                >
+              , qi::domain
+              , mpl::identity<extract_any_char_director<mpl::_> >
+            >
+            // char_('x'), wchar(L'x') --> literal_char
+          , meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_char_tag<proto::_arg, qi::domain>()
+                    >
+                  , basic_char_literal_meta_grammar
+                >
+              , qi::domain
+              , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
+            >
+            // lit("x"), wlit(L"x") --> literal_char
+          , meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_lit_tag<proto::_arg, qi::domain>()
+                    >
+                  , basic_char_literal_meta_grammar
+                >
+              , qi::domain
+              , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
+            >
+            // char_(F()) --> lazy_char
+          , meta_grammar::function1_rule<
+                qi::domain
+              , tag::char_
+              , lazy_char
+            >
+            // char_('x', 'z'), wchar(L'x', L'z') --> char_range
+          , meta_grammar::compose_function2_eval<
+                proto::function<
+                    proto::if_<
+                        is_char_tag<proto::_arg, qi::domain>()
+                    >
+                  , basic_char_literal_meta_grammar
+                  , basic_char_literal_meta_grammar
+                >
+              , qi::domain
+              , mpl::identity<extract_char_range_director<mpl::_, mpl::_> >
+            >
+            // char_(F1(), F2()) --> lazy_char_range
+          , meta_grammar::function2_rule<
+                qi::domain
+              , tag::char_
+              , lazy_char_range
+            >
+        >
+    {
+    };
+
+    // char_classes: alnum, alpha, cntrl, ... etc.
+    struct char_class_meta_grammar
+      : proto::or_<
+            // alnum, alpha, cntrl, ... etc.
+            meta_grammar::compose_empty<
+                proto::terminal<spirit::char_class::key<proto::_, proto::_> >
+              , qi::domain
+              , char_class<mpl::_>
+            >
+          , meta_grammar::compose_empty<
+                proto::terminal<spirit::char_class::lower_case_tag<proto::_> >
+              , qi::domain
+              , char_class<mpl::_>
+            >
+          , meta_grammar::compose_empty<
+                proto::terminal<spirit::char_class::upper_case_tag<proto::_> >
+              , qi::domain
+              , char_class<mpl::_>
+            >
+        >
+    {};
+
+    // ~x (where x is a char_parser)
+    struct negated_char_meta_grammar
+      : meta_grammar::compose_single<
+            proto::unary_expr<
+                proto::tag::complement
+              , char_meta_grammar
+            >
+          , qi::domain
+          , negated_char_parser<mpl::_>
+        >
+    {
+    };
+
+    // main char_meta_grammar
+    struct char_meta_grammar
+      : proto::or_<
+            char_meta_grammar1
+          , char_class_meta_grammar
+          , char_literal_meta_grammar
+          , negated_char_meta_grammar
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
+      : mpl::identity<char_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/debug.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
+#define BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM
+
+#if defined(BOOST_SPIRIT_DEBUG)
+#include <boost/spirit/home/qi/debug/simple_debug_macros.hpp>
+#include <boost/spirit/home/qi/debug/simple_debug.hpp>
+#else
+#include <boost/spirit/home/qi/debug/minimal_macros.hpp>
+#endif 
+
+#endif
Added: trunk/boost/spirit/home/qi/debug/detail/debug_handler.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug/detail/debug_handler.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,122 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM)
+#define BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM
+
+#include <boost/spirit/home/qi/nonterminal/detail/rule.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace debug
+{
+
+namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This class is to avoid linker problems and to ensure a real singleton
+    //  'level' variable
+    static int& get_trace_level()
+    {
+        static int level = 0;
+        return level;
+    }
+
+    struct trace_level
+    {
+        trace_level(int &level) 
+          : level(level) 
+        {
+            ++level;
+        }
+        ~trace_level()
+        {
+            --level;
+        }
+        
+        int& level;
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Iterator, typename Context, typename Skipper,
+        typename PreParseF, typename PostParseF
+    >
+    struct debug_handler 
+      : qi::detail::virtual_component_base<Iterator, Context, Skipper>
+    {
+        typedef 
+            qi::detail::virtual_component_base<Iterator, Context, Skipper> 
+        base_type;
+        typedef intrusive_ptr<base_type> pointer_type;
+        typedef typename base_type::skipper_type skipper_type;
+
+        debug_handler(pointer_type subject, std::string const& name,
+                bool trace, PreParseF preF, PostParseF postF)
+          : subject(subject), name(name), trace(trace), 
+            preF(preF), postF(postF)
+        {
+        }
+
+        template <typename Skipper_>
+        bool parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , Skipper_ const& skipper)
+        {
+            // execute embedded parser if tracing is disabled or if the 
+            // pre-parse hook returns true
+            bool r = false;
+            if (!trace || preF(name, subject, get_trace_level(), first, last)) 
+            {
+                {
+                    trace_level level(get_trace_level());
+                    
+                    // do the actual parsing
+                    Iterator i = first;
+                    r = subject->parse(i, last, context, skipper);
+                    if (r)
+                        first = i;
+                }
+                                    
+                // the post-parse hook gets executed only if tracing is enabled
+                if (trace)
+                    postF(r, name, subject, get_trace_level(), first, last);
+            }
+            return r;
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , skipper_type const& skipper)
+        {
+            return parse_main(first, last, context, skipper);
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , unused_type)
+        {
+            return parse_main(first, last, context, unused);
+        }
+
+        pointer_type subject;
+        std::string const& name;
+        bool trace;
+        PreParseF preF;
+        PostParseF postF;
+    };
+ 
+}   
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/debug/detail/print_node_info.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug/detail/print_node_info.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,129 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2003 Gustavo Guerra
+
+    Distributed under the Boost Software 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_PRINT_NODE_INFO_NOV_12_2007_1045AM)
+#define BOOST_SPIRIT_PRINT_NODE_INFO_NOV_12_2007_1045AM
+
+#include <cctype>     // iscntrl
+#include <iostream>
+#include <iomanip>
+
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace debug 
+{
+
+namespace detail
+{
+    struct token_printer_aux_for_chars
+    {
+        template<typename Char>
+        static void print(std::ostream& o, Char c)
+        {
+            using namespace std;    // allow for ADL to find the proper iscntrl
+            
+            if (c == static_cast<Char>('\a'))
+                o << "\\a";
+
+            else if (c == static_cast<Char>('\b'))
+                o << "\\b";
+
+            else if (c == static_cast<Char>('\f'))
+                o << "\\f";
+
+            else if (c == static_cast<Char>('\n'))
+                o << "\\n";
+
+            else if (c == static_cast<Char>('\r'))
+                o << "\\r";
+
+            else if (c == static_cast<Char>('\t'))
+                o << "\\t";
+
+            else if (c == static_cast<Char>('\v'))
+                o << "\\v";
+
+            else if (iscntrl(c))
+                o << "\\" << std::oct << static_cast<int>(c);
+
+            else
+                o << static_cast<char>(c);
+        }
+    };
+
+    // for token types where the comparison with char constants wouldn't work
+    struct token_printer_aux_for_other_types
+    {
+        template<typename Char>
+        static void print(std::ostream& o, Char c)
+        {
+            o << c;
+        }
+    };
+
+    template <typename Char>
+    struct token_printer_aux
+      : mpl::if_<
+            mpl::and_<
+                is_convertible<Char, char>,
+                is_convertible<char, Char> 
+            >,
+            token_printer_aux_for_chars,
+            token_printer_aux_for_other_types
+        >::type
+    {};
+
+    template<typename Char>
+    inline void token_printer(std::ostream& o, Char c)
+    {
+    // allow to customize the token printer routine
+#if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
+        token_printer_aux<Char>::print(o, c);
+#else
+        BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);
+#endif
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    inline void
+    print_node_info(bool hit, int level, bool close, std::string const& name,
+        Iterator /*first*/, Iterator const& /*last*/)
+    {
+        if (!name.empty())
+        {
+            for (int i = 0; i < level; ++i)
+                BOOST_SPIRIT_DEBUG_OUT << "  ";
+
+            if (close) {
+                if (hit)
+                    BOOST_SPIRIT_DEBUG_OUT << "/";
+                else
+                    BOOST_SPIRIT_DEBUG_OUT << "#";
+            }
+            
+//             BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
+//             for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
+//             {
+//                 if (first == last)
+//                     break;
+// 
+//                 token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
+//                 ++first;
+//             }
+//             BOOST_SPIRIT_DEBUG_OUT << "\"\n";
+            BOOST_SPIRIT_DEBUG_OUT << name << "\n";
+        }
+    }
+
+}
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/debug/minimal_macros.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug/minimal_macros.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,37 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_MINIMAL_MACROS_NOV_12_2007_1047AM)
+#define BOOST_SPIRIT_MINIMAL_MACROS_NOV_12_2007_1047AM
+
+#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
+#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  Minimum debugging tools support
+#if !defined(BOOST_SPIRIT_DEBUG_OUT)
+#define BOOST_SPIRIT_DEBUG_OUT std::cerr
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  Empty implementations of the debug macros above, if no debug support is 
+//  required
+#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
+#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)
+#endif
+
+#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
+#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)
+#endif
+
+#if !defined(BOOST_SPIRIT_DEBUG_NODE)
+#define BOOST_SPIRIT_DEBUG_NODE(r)
+#endif
+
+#endif
+
+
Added: trunk/boost/spirit/home/qi/debug/simple_debug.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug/simple_debug.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,72 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_SIMPLE_DEBUG_NOV_12_2007_1155AM)
+#define BOOST_SPIRIT_SIMPLE_DEBUG_NOV_12_2007_1155AM
+
+#include <boost/spirit/home/qi/debug/detail/debug_handler.hpp>
+#include <boost/spirit/home/qi/debug/detail/print_node_info.hpp>
+#include <boost/spirit/home/qi/nonterminal/rule.hpp>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi { namespace debug
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Simple pre-parse hook allowing to print the context before a rule is
+    //  parsed.
+    template <typename Subject, typename Iterator>
+    inline bool
+    simple_pre_parse(std::string const& name, Subject subject,
+        unsigned level, Iterator first, Iterator const& last)
+    {
+        detail::print_node_info(false, level, false, name, first, last);
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Simple post-parse hook allowing to print the context after a rule is
+    //  parsed.
+    template <typename Subject, typename Iterator>
+    inline void
+    simple_post_parse(bool hit, std::string const& name, Subject subject,
+        unsigned level, Iterator first, Iterator const& last)
+    {
+        detail::print_node_info(hit, level, true, name, first, last);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Nonterminal>
+    inline void
+    enable_simple_debug_support(Nonterminal& r, bool trace)
+    {
+        typedef typename Nonterminal::iterator_type iterator_type;
+        typedef typename Nonterminal::pointer_type pointer_type;
+
+        typedef bool (*pre_parse_functor_type)(std::string const&,
+            pointer_type, unsigned, iterator_type, iterator_type const&);
+        typedef void (*post_parse_functor_type)(bool, std::string const&,
+            pointer_type, unsigned, iterator_type, iterator_type const&);
+
+        typedef
+            detail::debug_handler<
+                iterator_type,
+                typename Nonterminal::base_type::context_type,
+                typename Nonterminal::skipper_type,
+                pre_parse_functor_type,
+                post_parse_functor_type>
+        simple_debug_handler;
+
+        pre_parse_functor_type pre = 
+            &simple_pre_parse<pointer_type, iterator_type>;
+        post_parse_functor_type post = 
+            &simple_post_parse<pointer_type, iterator_type>;
+        decorate<simple_debug_handler>(r, r.name(), trace, pre, post);
+    }
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/debug/simple_debug_macros.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/debug/simple_debug_macros.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,46 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_SIMPLE_DEBUG_MACROS_NOV_12_2007_0828AM)
+#define BOOST_SPIRIT_SIMPLE_DEBUG_MACROS_NOV_12_2007_0828AM
+
+#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
+#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  Make sure all required debug helper macros are defined properly
+#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
+#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)                           \
+        r.name(n);                                                            \
+        boost::spirit::qi::debug::enable_simple_debug_support(r, t)           \
+    /**/
+#endif
+
+#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
+#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)                                   \
+        if (r.name().empty()) r.name(#r);                                     \
+        boost::spirit::qi::debug::enable_simple_debug_support(r, t)           \
+    /**/
+#endif
+
+#if !defined(BOOST_SPIRIT_DEBUG_NODE)
+#define BOOST_SPIRIT_DEBUG_NODE(r)                                            \
+        BOOST_SPIRIT_DEBUG_TRACE_NODE(r, true)                                \
+    /**/
+#endif
+
+//  number of input tokens to print while debugging
+#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
+#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
+#endif
+
+//  The stream to use for debug output
+#if !defined(BOOST_SPIRIT_DEBUG_OUT)
+#define BOOST_SPIRIT_DEBUG_OUT std::cerr
+#endif
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/alternative_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/alternative_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,81 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ALTERNATIVE_FUNCTION_APR_23_2007_1046AM)
+#define SPIRIT_ALTERNATIVE_FUNCTION_APR_23_2007_1046AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Iterator, typename Context, typename Skipper,
+        typename Attribute>
+    struct alternative_function
+    {
+        alternative_function(
+            Iterator& first, Iterator const& last, Context& context,
+            Skipper const& skipper, Attribute& attr)
+          : first(first), last(last), context(context), skipper(skipper),
+            attr(attr)
+        {
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if the parser succeeds
+            typedef typename Component::director director;
+            typename
+                traits::attribute_of<
+                    qi::domain, Component, Context, Iterator>::type
+            val;
+
+            if (director::parse(component, first, last, context, skipper, val))
+            {
+                attr = val;
+                return true;
+            }
+            return false;
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+        Attribute& attr;
+    };
+
+    template <typename Iterator, typename Context, typename Skipper>
+    struct alternative_function<Iterator, Context, Skipper, unused_type const>
+    {
+        alternative_function(
+            Iterator& first, Iterator const& last, Context& context,
+            Skipper const& skipper, unused_type)
+          : first(first), last(last), context(context), skipper(skipper)
+        {
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if the parser succeeds
+            typedef typename Component::director director;
+            return director::parse(component, first, last, context, skipper,
+                unused);
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/assign_to.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,125 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM)
+#define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/ref.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    namespace construct_ 
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  This is used to allow to overload of the attribute creation for 
+        //  arbitrary types
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Attribute, typename Iterator>
+        inline void 
+        construct(Attribute& attr, Iterator const& first, Iterator const& last)
+        {
+            attr = Attribute(first, last);
+        }
+        
+        template <typename Attribute, typename T>
+        inline void 
+        construct(Attribute& attr, T const& val)
+        {
+            attr = val;
+        }
+        
+        template <typename Attribute, typename T>
+        inline void 
+        construct(Attribute& attr, T& val)
+        {
+            attr = val;
+        }
+
+        template <typename Attribute, typename T>
+        inline void 
+        construct(reference_wrapper<Attribute> attr, T const& val)
+        {
+            attr = val;
+        }
+        
+        template <typename Attribute, typename T>
+        inline void 
+        construct(reference_wrapper<Attribute> attr, T& val)
+        {
+            attr = val;
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This file contains assignment utilities. The utilities provided also
+    //  accept spirit's unused_type; all no-ops. Compiler optimization will
+    //  easily strip these away.
+    ///////////////////////////////////////////////////////////////////////////
+
+    template <typename Iterator, typename Attribute>
+    inline void
+    assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
+    {
+        using namespace construct_;
+        construct(attr, first, last);
+    }
+
+    template <typename Iterator>
+    inline void
+    assign_to(Iterator const& /*first*/, Iterator const& /*last*/, unused_type)
+    {
+    }
+
+    template <typename T, typename Attribute>
+    inline void
+    assign_to(T const& val, Attribute& attr)
+    {
+        using namespace construct_;
+        construct(attr, val);
+    }
+
+    template <typename T, typename Attribute>
+    inline void
+    assign_to(T& val, Attribute& attr)
+    {
+        using namespace construct_;
+        construct(attr, val);
+    }
+
+    template <typename T, typename Attribute>
+    inline void
+    assign_to(T const& val, reference_wrapper<Attribute> attr)
+    {
+        using namespace construct_;
+        construct(attr, val);
+    }
+
+    template <typename T, typename Attribute>
+    inline void
+    assign_to(T& val, reference_wrapper<Attribute> attr)
+    {
+        using namespace construct_;
+        construct(attr, val);
+    }
+
+    template <typename T>
+    inline void
+    assign_to(T const& /*val*/, unused_type)
+    {
+    }
+
+    template <typename T>
+    inline void
+    assign_to(T& /*val*/, unused_type)
+    {
+    }
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/construct.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/construct.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,144 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM)
+#define BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/parse.hpp>
+#include <boost/spirit/home/qi/numeric.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    namespace construct_
+    {
+        ///////////////////////////////////////////////////////////////////////
+        //  We provide overloads for the construct customization point for all
+        //  built in types
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator>
+        inline void
+        construct(char& attr, Iterator const& first, Iterator const& last)
+        {
+            attr = *first;
+        }
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+        // wchar_t is intrinsic
+        template <typename Iterator>
+        inline void
+        construct(wchar_t& attr, Iterator const& first, Iterator const& last)
+        {
+            attr = *first;
+        }
+        template <typename Iterator>
+        inline void
+        construct(unsigned short& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, ushort, attr);
+        }
+#else
+        // is wchar_t is not an intrinsic type, treat wchar_t only
+        template <typename Iterator>
+        inline void
+        construct(wchar_t& attr, Iterator const& first, Iterator const& last)
+        {
+            attr = *first;
+        }
+#endif
+
+        template <typename Iterator>
+        inline void
+        construct(short& attr, Iterator const& first, Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, short_, attr);
+        }
+
+        template <typename Iterator>
+        inline void
+        construct(int& attr, Iterator const& first, Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, int_, attr);
+        }
+        template <typename Iterator>
+        inline void
+        construct(unsigned int& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, uint_, attr);
+        }
+
+        template <typename Iterator>
+        inline void
+        construct(long& attr, Iterator const& first, Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, long_, attr);
+        }
+        template <typename Iterator>
+        inline void
+        construct(unsigned long& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, ulong, attr);
+        }
+
+#ifdef BOOST_HAS_LONG_LONG
+        template <typename Iterator>
+        inline void
+        construct(boost::long_long_type& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, long_long, attr);
+        }
+        template <typename Iterator>
+        inline void
+        construct(boost::ulong_long_type& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, ulong_long, attr);
+        }
+#endif
+
+        template <typename Iterator>
+        inline void
+        construct(float& attr, Iterator const& first, Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, float_, attr);
+        }
+
+        template <typename Iterator>
+        inline void
+        construct(double& attr, Iterator const& first, Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, double_, attr);
+        }
+
+        template <typename Iterator>
+        inline void
+        construct(long double& attr, Iterator const& first,
+            Iterator const& last)
+        {
+            Iterator first_ = first;
+            parse(first_, last, long_double, attr);
+        }
+    }
+    
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/expect_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/expect_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,80 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM)
+#define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <
+        typename Iterator, typename Context
+      , typename Skipper, typename Exception>
+    struct expect_function
+    {
+        expect_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+          : first(first)
+          , last(last)
+          , context(context)
+          , skipper(skipper)
+          , is_first(true)
+        {
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, Attribute& attr)
+        {
+            // if we are testing the first component in the sequence,
+            // return true if the parser fails, if this not the first
+            // component, throw exception if the parser fails
+            typedef typename Component::director director;
+            if (!director::parse(component, first, last, context, skipper, attr))
+            {
+                if (is_first)
+                {
+                    is_first = false;
+                    return true;
+                }
+                Exception x = {first, last, director::what(component) };
+                throw x;
+            }
+            is_first = false;
+            return false;
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // if we are testing the first component in the sequence,
+            // return true if the parser fails, if this not the first
+            // component, throw exception if the parser fails
+            typedef typename Component::director director;
+            if (!director::parse(component, first, last, context, skipper, unused))
+            {
+                if (is_first)
+                {
+                    is_first = false;
+                    return true;
+                }
+                Exception x = {first, last, director::what(component) };
+                throw x;
+            }
+            is_first = false;
+            return false;
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+        bool is_first;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/fail_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/fail_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,50 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_FAIL_FUNCTION_APR_22_2006_0159PM)
+#define SPIRIT_FAIL_FUNCTION_APR_22_2006_0159PM
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Iterator, typename Context, typename Skipper>
+    struct fail_function
+    {
+        fail_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+          : first(first)
+          , last(last)
+          , context(context)
+          , skipper(skipper)
+        {
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, Attribute& attr)
+        {
+            // return true if the parser fails
+            typedef typename Component::director director;
+            return !director::parse(component, first, last, context, skipper, attr);
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if the parser fails
+            typedef typename Component::director director;
+            return !director::parse(component, first, last, context, skipper, unused);
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/pass_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/pass_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,65 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_PASS_FUNCTION_FEB_05_2007_1138AM)
+#define SPIRIT_PASS_FUNCTION_FEB_05_2007_1138AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/optional.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Iterator, typename Context, typename Skipper>
+    struct pass_function
+    {
+        pass_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+          : first(first)
+          , last(last)
+          , context(context)
+          , skipper(skipper)
+        {
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, Attribute& attr)
+        {
+            // return true if the parser succeeds
+            typedef typename Component::director director;
+            return director::parse(component, first, last, context, skipper, attr);
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, boost::optional<Attribute>& attr)
+        {
+            // return true if the parser succeeds
+            typedef typename Component::director director;
+            Attribute val;
+            if (director::parse(component, first, last, context, skipper, val))
+            {
+                attr = val;
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if the parser succeeds
+            typedef typename Component::director director;
+            return director::parse(component, first, last, context, skipper, unused);
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/permute_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/permute_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM)
+#define SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/optional.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Iterator, typename Context, typename Skipper>
+    struct permute_function
+    {
+        permute_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+          : first(first)
+          , last(last)
+          , context(context)
+          , skipper(skipper)
+        {
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, Attribute& attr)
+        {
+            // return true if the parser succeeds and the slot is not yet taken
+            typedef typename Component::director director;
+            if (!*taken
+                && director::parse(component, first, last, context, skipper, attr))
+            {
+                *taken = true;
+                ++taken;
+                return true;
+            }
+            ++taken;
+            return false;
+        }
+
+        template <typename Component, typename Attribute>
+        bool operator()(Component const& component, boost::optional<Attribute>& attr)
+        {
+            // return true if the parser succeeds and the slot is not yet taken
+            typedef typename Component::director director;
+            Attribute val;
+            if (!*taken
+                && director::parse(component, first, last, context, skipper, val))
+            {
+                attr = val;
+                *taken = true;
+                ++taken;
+                return true;
+            }
+            ++taken;
+            return false;
+        }
+
+        template <typename Component>
+        bool operator()(Component const& component)
+        {
+            // return true if the parser succeeds and the slot is not yet taken
+            typedef typename Component::director director;
+            if (!*taken
+                && director::parse(component, first, last, context, skipper, unused))
+            {
+                *taken = true;
+                ++taken;
+                return true;
+            }
+            ++taken;
+            return false;
+        }
+
+        Iterator& first;
+        Iterator const& last;
+        Context& context;
+        Skipper const& skipper;
+        bool* taken;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/detail/string_parse.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/detail/string_parse.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,81 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM)
+#define BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM
+
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Char, typename Iterator, typename Attribute>
+    inline bool string_parse(
+        Char const* str
+      , Iterator& first, Iterator const& last, Attribute& attr)
+    {
+        Iterator i = first;
+        Char ch;
+
+        for (; !!(ch = *str); ++str, ++i)
+            if (i == last || (ch != *i))
+                return false;
+        detail::assign_to(first, i, attr);
+        first = i;
+        return true;
+    }
+
+    template <typename String, typename Iterator, typename Attribute>
+    inline bool string_parse(
+        String const& str
+      , Iterator& first, Iterator const& last, Attribute& attr)
+    {
+        Iterator i = first;
+        typename String::const_iterator stri = str.begin();
+        typename String::const_iterator str_last = str.end();
+
+        for (; stri != str_last; ++stri, ++i)
+            if (i == last || (*stri != *i))
+                return false;
+        detail::assign_to(first, i, attr);
+        first = i;
+        return true;
+    }
+
+    template <typename Char, typename Iterator, typename Attribute>
+    inline bool string_parse(
+        Char const* uc_i, Char const* lc_i
+      , Iterator& first, Iterator const& last, Attribute& attr)
+    {
+        Iterator i = first;
+
+        for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
+            if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
+                return false;
+        detail::assign_to(first, i, attr);
+        first = i;
+        return true;
+    }
+
+    template <typename String, typename Iterator, typename Attribute>
+    inline bool string_parse(
+        String const& ucstr, String const& lcstr
+      , Iterator& first, Iterator const& last, Attribute& attr)
+    {
+        typename String::const_iterator uc_i = ucstr.begin();
+        typename String::const_iterator uc_last = ucstr.end();
+        typename String::const_iterator lc_i = lcstr.begin();
+        Iterator i = first;
+
+        for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
+            if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
+                return false;
+        detail::assign_to(first, i, attr);
+        first = i;
+        return true;
+    }
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/directive.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/directive.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,15 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_DIRECTIVE_FEB_05_2007_0313PM)
+#define BOOST_SPIRIT_DIRECTIVE_FEB_05_2007_0313PM
+
+#include <boost/spirit/home/qi/directive/lexeme.hpp>
+#include <boost/spirit/home/qi/directive/omit.hpp>
+#include <boost/spirit/home/qi/directive/raw.hpp>
+#include <boost/spirit/home/qi/directive/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/directive/lexeme.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/directive/lexeme.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,68 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_LEXEME_MARCH_24_2007_0802AM)
+#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct lexeme_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, subject_type, Context, Iterator>::type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            qi::skip(first, last, skipper);
+            return director::parse(
+                spirit::subject(component), first, last, context, unused, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "lexeme[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/directive/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/directive/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,79 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0320PM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0320PM
+
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/iso8859_1.hpp>
+#include <boost/spirit/home/support/ascii.hpp>
+#include <boost/spirit/home/support/standard.hpp>
+#include <boost/spirit/home/support/standard_wide.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct lexeme_director;
+    struct omit_director;
+    struct raw_director;
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // directive meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+    struct directive_meta_grammar
+      : proto::or_<
+            meta_grammar::deep_directive_meta_grammar<
+                spirit::char_class::no_case_tag<proto::_>
+              , main_meta_grammar
+            >
+          , meta_grammar::binary_rule_rhs<
+                qi::domain, proto::tag::subscript, lexeme_director
+              , proto::terminal<tag::lexeme>, main_meta_grammar
+            >
+          , meta_grammar::binary_rule_rhs<
+                qi::domain, proto::tag::subscript, omit_director
+              , proto::terminal<tag::omit>, main_meta_grammar
+            >
+          , meta_grammar::binary_rule_rhs<
+                qi::domain, proto::tag::subscript, raw_director
+              , proto::terminal<tag::raw>, main_meta_grammar
+            >
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
+      : mpl::identity<directive_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/directive/omit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/directive/omit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,59 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_OMIT_MARCH_24_2007_0802AM)
+#define SPIRIT_OMIT_MARCH_24_2007_0802AM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct omit_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute&)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            qi::skip(first, last, skipper);
+            return director::parse(
+                spirit::subject(component), first, last, context, skipper, unused);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "omit[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/directive/raw.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/directive/raw.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,66 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_RAW_APRIL_9_2007_0912AM)
+#define SPIRIT_RAW_APRIL_9_2007_0912AM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/range/iterator_range.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct raw_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef iterator_range<Iterator> type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            qi::skip(first, last, skipper);
+            Iterator i = first;
+            if (director::parse(
+                spirit::subject(component), i, last, context, skipper, unused))
+            {
+                attr = Attribute(first, i);
+                first = i;
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "raw[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/domain.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/domain.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,15 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_DOMAIN_JAN_29_2007_0954AM)
+#define BOOST_SPIRIT_DOMAIN_JAN_29_2007_0954AM
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct domain {};
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,47 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_JAN_29_2007_0937AM)
+#define BOOST_SPIRIT_META_GRAMMAR_JAN_29_2007_0937AM
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/placeholders.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    // Check if Expr is a valid RD expression
+    template <typename Expr, typename Enable = void>
+    struct is_valid_expr : mpl::false_ {};
+
+    // Return a suitable transform for the given Expr
+    template <typename Expr, typename Enable = void>
+    struct expr_transform;
+
+    struct main_meta_grammar
+      : meta_grammar::if_transform<
+            is_valid_expr<proto::_>() 
+          , expr_transform<proto::_> 
+        >
+    {
+    };
+}}}
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The spirit qi domain meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    template <>
+    struct grammar<qi::domain>
+    {
+        typedef qi::main_meta_grammar type;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,14 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NONTERMINAL_FEB_12_2007_1018AM)
+#define BOOST_SPIRIT_NONTERMINAL_FEB_12_2007_1018AM
+
+#include <boost/spirit/home/qi/nonterminal/meta_grammar.hpp>
+#include <boost/spirit/home/qi/nonterminal/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/detail/error_handler.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/error_handler.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,100 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ERROR_HANDLER_APR_29_2007_1042PM)
+#define BOOST_SPIRIT_ERROR_HANDLER_APR_29_2007_1042PM
+
+#include <boost/spirit/home/qi/nonterminal/detail/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/error_handler_result.hpp>
+#include <boost/spirit/home/qi/operator/expect.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <
+        typename Iterator, typename Context
+      , typename Skipper, typename F, error_handler_result action
+    >
+    struct error_handler : virtual_component_base<Iterator, Context, Skipper>
+    {
+        typedef virtual_component_base<Iterator, Context, Skipper> base_type;
+        typedef intrusive_ptr<base_type> pointer_type;
+        typedef typename base_type::skipper_type skipper_type;
+
+        error_handler(pointer_type subject, F f)
+          : subject(subject)
+          , f(f)
+        {
+        }
+
+        template <typename Skipper_>
+        bool parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , Skipper_ const& skipper)
+        {
+            while (true)
+            {
+                try
+                {
+                    Iterator i = first;
+                    bool r = subject->parse(i, last, context, skipper);
+                    if (r)
+                        first = i;
+                    return r;
+                }
+                catch (expectation_failure<Iterator> const& x)
+                {
+                    typedef
+                        fusion::vector<
+                            Iterator&
+                          , Iterator const&
+                          , Iterator const&
+                          , std::string>
+                    params;
+                    error_handler_result r = action;
+                    params args(first, last, x.first, x.what);
+                    f(args, context, r);
+
+                    switch (r)
+                    {
+                        case fail: return false;
+                        case retry: continue;
+                        case accept: return true;
+                        case rethrow: throw x;
+                    }
+                }
+            }
+            return false;
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , skipper_type const& skipper)
+        {
+            return parse_main(first, last, context, skipper);
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , unused_type)
+        {
+            return parse_main(first, last, context, unused);
+        }
+
+        pointer_type subject;
+        F f;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/detail/rule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/rule.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,196 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RULE_FEB_12_2007_0440PM)
+#define BOOST_SPIRIT_RULE_FEB_12_2007_0440PM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/detail/atomic_count.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/function_types/is_function.hpp>
+#include <boost/assert.hpp>
+#include <algorithm>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    template <typename Iterator, typename Context, typename Skipper>
+    struct virtual_component_base
+    {
+        struct no_skipper {};
+
+        typedef typename
+            mpl::eval_if<
+                is_same<Skipper, unused_type>
+              , mpl::identity<no_skipper>
+              , result_of::as_component<qi::domain, Skipper>
+            >::type
+        skipper_type;
+
+        virtual_component_base()
+          : use_count(0)
+        {
+        }
+
+        virtual ~virtual_component_base()
+        {
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , skipper_type const& skipper) = 0;
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , unused_type) = 0;
+
+        boost::detail::atomic_count use_count;
+    };
+
+    template <typename Iterator, typename Context, typename Skipper>
+    inline void
+    intrusive_ptr_add_ref(virtual_component_base<Iterator, Context, Skipper>* p)
+    {
+        ++p->use_count;
+    }
+
+    template <typename Iterator, typename Context, typename Skipper>
+    inline void
+    intrusive_ptr_release(virtual_component_base<Iterator, Context, Skipper>* p)
+    {
+        if (--p->use_count == 0)
+            delete p;
+    }
+
+    template <
+        typename Iterator, typename Component
+      , typename Context, typename Skipper
+      , typename Auto
+    >
+    struct virtual_component : virtual_component_base<Iterator, Context, Skipper>
+    {
+        typedef virtual_component_base<Iterator, Context, Skipper> base_type;
+        typedef typename base_type::skipper_type skipper_type;
+        typedef typename base_type::no_skipper no_skipper;
+
+        virtual_component(Component const& component)
+          : component(component)
+        {
+        }
+
+        virtual ~virtual_component()
+        {
+        }
+
+        template <typename T>
+        static void clear(T& attr)
+        {
+            attr = T();
+        }
+
+        template <typename Skipper_>
+        bool parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , Skipper_ const& skipper
+          , mpl::false_)
+        {
+            // If Auto is false, the component's attribute is unused.
+
+            typedef typename Component::director director;
+            return director::parse(
+                component, first, last, context, skipper, unused);
+        }
+
+        template <typename Skipper_>
+        bool parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , Skipper_ const& skipper
+          , mpl::true_)
+        {
+            // If Auto is true, we synthesize the rule's attribute and pass
+            // it on to the component. On successful parse, this attribute
+            // is swapped back to the the rule's attribute.
+
+            typename
+                remove_reference<
+                    typename fusion::result_of::value_at_c<
+                        typename fusion::result_of::value_at_c<Context, 0>::type
+                      , 0
+                    >::type
+                >::type
+            attribute; // default constructed
+            typedef typename Component::director director;
+            if (director::parse(
+                component, first, last, context, skipper, attribute))
+            {
+                // $$$ need to optimize this for fusion sequences $$$
+                std::swap(fusion::at_c<0>(fusion::at_c<0>(context)), attribute);
+                return true;
+            }
+            return false;
+        }
+
+        bool parse_main(
+            Iterator& /*first*/
+          , Iterator const& /*last*/
+          , Context&
+          , no_skipper
+          , mpl::false_)
+        {
+            BOOST_ASSERT(false); // this should never be called
+            return false;
+        }
+
+        bool parse_main(
+            Iterator& /*first*/
+          , Iterator const& /*last*/
+          , Context& /*context*/
+          , no_skipper
+          , mpl::true_)
+        {
+            BOOST_ASSERT(false); // this should never be called
+            return false;
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , skipper_type const& skipper)
+        {
+            return parse_main(first, last, context, skipper, Auto());
+        }
+
+        virtual bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Context& context
+          , unused_type)
+        {
+            return parse_main(first, last, context, unused, Auto());
+        }
+
+        Component component;
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/error_handler_result.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/error_handler_result.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ERROR_HANDLER_RESULT_APR_29_2007_1042PM)
+#define BOOST_SPIRIT_ERROR_HANDLER_RESULT_APR_29_2007_1042PM
+
+namespace boost { namespace spirit { namespace qi
+{
+    enum error_handler_result
+    {
+        fail
+      , retry
+      , accept
+      , rethrow
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,144 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_GRAMMAR_FEB_19_2007_0236PM)
+#define BOOST_SPIRIT_GRAMMAR_FEB_19_2007_0236PM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/nonterminal/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal_director.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Definition>
+    struct grammar
+      : nonterminal<
+            grammar<Definition>
+          , typename Definition::sig_type
+          , typename Definition::locals_type
+        >
+    {
+        typedef typename Definition::sig_type sig_type;
+        typedef typename Definition::locals_type locals_type;
+        typedef typename Definition::skipper_type skipper_type;
+        typedef typename Definition::start_type start_type;
+        typedef typename Definition::iterator_type iterator_type;
+
+        template <typename Definition_>
+        explicit grammar(Definition_ const& definition)
+          : definition(definition)
+          , start(definition.start)
+        {
+        }
+
+        template <typename Definition_, typename Start>
+        grammar(Definition_ const& definition, Start const& start)
+          : definition(definition)
+          , start(start)
+        {
+        }
+
+    private:
+
+        template <typename Iterator, typename Context, typename Skipper>
+        bool parse(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper) const
+        {
+            return start.parse(first, last, context, skipper);
+        }
+
+        std::string what() const
+        {
+            if (definition.name().empty())
+            {
+                return start.what();
+            }
+            else
+            {
+                return definition.name();
+            }
+        }
+
+        friend struct nonterminal_director;
+        Definition const& definition;
+        start_type const& start;
+    };
+
+    template <
+        typename Iterator
+      , typename T0 = unused_type
+      , typename T1 = unused_type
+      , typename T2 = unused_type
+    >
+    struct grammar_def : noncopyable
+    {
+        typedef Iterator iterator_type;
+        typedef qi::rule<Iterator, T0, T1, T2> start_type;
+        typedef typename start_type::sig_type sig_type;
+        typedef typename start_type::locals_type locals_type;
+        typedef typename start_type::skipper_type skipper_type;
+
+        grammar_def(std::string const& name_ = std::string())
+          : name_(name_) {}
+
+        std::string name() const
+        {
+            return name_;
+        }
+
+        void name(std::string const& name__)
+        {
+            name_ = name__;
+        }
+
+        std::string name_;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Generator functions helping to construct a proper grammar object 
+    //  instance
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Definition>
+    inline grammar<Definition> 
+    make_parser(Definition const& def)
+    {
+        return grammar<Definition>(def);
+    }
+    
+    template <typename Definition, typename Start>
+    inline grammar<Definition> 
+    make_parser(Definition const& def, Start const& start)
+    {
+        return grammar<Definition>(def, start);
+    }
+    
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // forward declaration only (the default specialization is defined in the 
+    // file parse.hpp)
+    template <typename Parser, typename Skipper>
+    struct skipper_is_compatible;
+    
+    // If the parser is a grammar, then the skipper must be convertible to
+    // the skipper used with this grammar. 
+    template <typename Definition, typename Skipper>
+    struct skipper_is_compatible<qi::grammar<Definition>, Skipper>
+      : is_convertible<Skipper, typename qi::grammar<Definition>::skipper_type>
+    {
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,61 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_12_2007_0534PM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_12_2007_0534PM
+
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/nonterminal/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // nonterminal meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct nonterminal_meta_grammar
+      : meta_grammar::terminal_rule<
+            qi::domain
+          , nonterminal_holder<proto::_, proto::_>
+          , nonterminal_director
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, nonterminal_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, nonterminal_meta_grammar> >::type>
+      : mpl::identity<nonterminal_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/nonterminal.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,142 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NONTERMINAL_FEB_19_2007_0236PM)
+#define BOOST_SPIRIT_NONTERMINAL_FEB_19_2007_0236PM
+
+#include <boost/spirit/home/qi/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/home/support/argument.hpp>
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/is_function.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/joint_view.hpp>
+#include <boost/fusion/include/single_view.hpp>
+
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/preprocessor/enum_params.hpp>
+#include <boost/preprocessor/enum_params_with_a_default.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Derived, typename Sig, typename Locals>
+    struct nonterminal
+      : proto::extends<
+            typename make_nonterminal_holder<
+                Derived const*, Derived
+            >::type
+          , Derived
+        >
+    {
+        typedef Sig sig_type;
+        typedef typename function_types::result_type<sig_type>::type attr_type_;
+
+        // This is the nonterminal return type
+        typedef typename
+            mpl::if_<
+                is_same<attr_type_, void>
+              , unused_type
+              , attr_type_
+            >::type
+        attr_type;
+        typedef typename add_reference<attr_type>::type attr_reference_type;
+
+        // param_types is a sequence of types passed as parameters to the nonterminal
+        typedef typename function_types::parameter_types<sig_type>::type param_types;
+
+        // locals_type is a sequence of types to be used as local variables
+        typedef typename fusion::result_of::as_vector<Locals>::type locals_type;
+
+        //  The overall context_type consist of a tuple with:
+        //      1) a tuple of the return value and parameters
+        //      2) the locals
+        typedef fusion::vector<
+                typename fusion::result_of::as_vector<
+                    fusion::joint_view<
+                        fusion::single_view<attr_reference_type>
+                      , param_types
+                    >
+                >::type
+              , typename fusion::result_of::as_vector<locals_type>::type
+            >
+        context_type;
+
+        typedef nonterminal<Derived, Sig, Locals> self_type;
+        typedef nonterminal_holder<Derived const*, Derived> nonterminal_holder_;
+        typedef typename proto::terminal<nonterminal_holder_>::type nonterminal_tag;
+        typedef proto::extends<nonterminal_tag, Derived> base_type;
+
+        explicit nonterminal()
+          : base_type(make_tag())
+        {
+        }
+
+        // bring in the operator() overloads
+        #include <boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp>
+
+    private:
+
+        nonterminal_tag make_tag() const
+        {
+            nonterminal_tag xpr = {{static_cast<Derived const*>(this)}};
+            return xpr;
+        }
+    };
+
+    template <typename Derived, typename T0, typename T1, typename T2>
+    struct make_nonterminal
+    {
+        typedef mpl::vector<T0, T1, T2> types;
+        typedef function_types::is_function<mpl::_> is_function;
+        typedef spirit::detail::is_locals<mpl::_> is_locals;
+        typedef spirit::traits::is_component<qi::domain, mpl::_> is_skipper;
+
+        typedef typename mpl::find_if<types, is_function>::type sig_;
+        typedef typename mpl::find_if<types, is_locals>::type locals_;
+        typedef typename mpl::find_if<types, is_skipper>::type skipper_;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<sig_, typename mpl::end<types>::type>
+              , mpl::identity<unused_type()>
+              , mpl::deref<sig_>
+            >::type
+        sig_type;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<locals_, typename mpl::end<types>::type>
+              , mpl::identity<locals<> >
+              , mpl::deref<locals_>
+            >::type
+        locals_type;
+
+        typedef typename
+            mpl::eval_if<
+                is_same<skipper_, typename mpl::end<types>::type>
+              , mpl::identity<unused_type>
+              , mpl::deref<skipper_>
+            >::type
+        skipper_type;
+
+        typedef nonterminal<Derived, sig_type, locals_type> type;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/nonterminal_director.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/nonterminal_director.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,170 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NONTERMINAL_DIRECTOR_FEB_19_2007_0259PM)
+#define BOOST_SPIRIT_NONTERMINAL_DIRECTOR_FEB_19_2007_0259PM
+
+#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/support/nonterminal/detail/expand_arg.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/join.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct nonterminal_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename result_of::subject<Component>::type nonterminal_holder;
+            typedef typename nonterminal_holder::nonterminal_type::attr_type type;
+        };
+
+        template <
+            typename NonterminalContext, typename Nonterminal
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse_nonterminal(
+            nonterminal_object<Nonterminal> const& x
+          , Iterator& first, Iterator const& last
+          , Context& /*caller_context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            // the nonterminal_holder holds an actual nonterminal_object
+            typedef typename Nonterminal::locals_type locals_type;
+            fusion::single_view<Attribute&> front(attr);
+            NonterminalContext context(front, locals_type());
+            return x.obj.parse(first, last, context, skipper);
+        }
+
+        template <
+            typename NonterminalContext, typename Nonterminal
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse_nonterminal(
+            Nonterminal const* ptr
+          , Iterator& first, Iterator const& last
+          , Context& /*caller_context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            // the nonterminal_holder holds a pointer to a nonterminal
+            typedef typename Nonterminal::locals_type locals_type;
+            fusion::single_view<Attribute&> front(attr);
+            NonterminalContext context(front, locals_type());
+            return ptr->parse(first, last, context, skipper);
+        }
+
+        template <
+            typename NonterminalContext, typename Nonterminal, typename FSequence
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse_nonterminal(
+            parameterized_nonterminal<Nonterminal, FSequence> const& x
+          , Iterator& first, Iterator const& last
+          , Context& caller_context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            // the nonterminal_holder holds a parameterized_nonterminal
+            typedef typename Nonterminal::locals_type locals_type;
+            fusion::single_view<Attribute&> front(attr);
+            NonterminalContext context(
+                fusion::join(
+                    front
+                  , fusion::transform(
+                        x.fseq
+                      , spirit::detail::expand_arg<Context>(caller_context)
+                    )
+                )
+              , locals_type()
+            );
+            return x.ptr->parse(first, last, context, skipper);
+        }
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr_)
+        {
+            // main entry point
+
+            typedef typename
+                result_of::subject<Component>::type
+            nonterminal_holder;
+
+            //  The overall context_type consist of a tuple with:
+            //      1) a tuple of the return value and parameters
+            //      2) the locals
+            //  if no signature is specified the first tuple contains
+            //  an unused_type element at position zero only.
+
+            typedef typename
+                nonterminal_holder::nonterminal_type::context_type
+            context_type;
+
+            //  attr_type is the return type as specified by the associated
+            //  nonterminal signature, if no signature is specified this is
+            //  the unused_type
+            typedef typename
+                nonterminal_holder::nonterminal_type::attr_type
+            attr_type;
+
+            // create an attribute if one is not supplied
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>
+              , attr_type
+              , Attribute&>::type
+            attr = spirit::detail::make_value<attr_type>::call(attr_);
+
+            return parse_nonterminal<context_type>(
+                subject(component).held
+              , first, last, context, skipper, attr
+            );
+        }
+
+        template <typename Nonterminal>
+        static std::string what_nonterminal(nonterminal_object<Nonterminal> const& x)
+        {
+            // the nonterminal_holder holds an actual nonterminal_object
+            return x.obj.what();
+        }
+
+        template <typename Nonterminal>
+        static std::string what_nonterminal(Nonterminal const* ptr)
+        {
+            // the nonterminal_holder holds a pointer to a nonterminal
+            return ptr->what();
+        }
+
+        template <typename Nonterminal, typename FSequence>
+        static std::string what_nonterminal(
+            parameterized_nonterminal<Nonterminal, FSequence> const& x)
+        {
+            // the nonterminal_holder holds a parameterized_nonterminal
+            return x.ptr->what();
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return what_nonterminal(subject(component).held);
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/nonterminal/rule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/rule.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,385 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_RULE_FEB_12_2007_1020AM)
+#define BOOST_SPIRIT_RULE_FEB_12_2007_1020AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal.hpp>
+#include <boost/spirit/home/qi/nonterminal/detail/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/detail/error_handler.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#endif
+
+namespace boost { namespace spirit { namespace qi
+{
+    // forward declarations
+    template <typename Definition>
+    struct grammar;
+    namespace detail { struct rule_decorator; }
+
+    template <
+        typename Iterator
+      , typename T0 = unused_type
+      , typename T1 = unused_type
+      , typename T2 = unused_type
+    >
+    struct rule
+      : make_nonterminal<rule<Iterator, T0, T1, T2>, T0, T1, T2>::type
+    {
+        typedef
+            make_nonterminal<rule<Iterator, T0, T1, T2>, T0, T1, T2>
+        make_nonterminal_;
+
+        typedef typename make_nonterminal_::skipper_type skipper_type;
+        typedef typename make_nonterminal_::type base_type;
+        typedef Iterator iterator_type;
+        typedef rule<Iterator, T0, T1, T2> self_type;
+
+        typedef
+            detail::virtual_component_base<
+                Iterator
+              , typename base_type::context_type
+              , skipper_type
+            >
+        virtual_component;
+
+        typedef intrusive_ptr<virtual_component> pointer_type;
+
+        rule(std::string const& name_ = std::string())
+          : name_(name_) {}
+
+        ~rule() {}
+
+        rule(rule const& rhs)
+          : ptr(rhs.ptr)
+          , name_(rhs.name_)
+        {
+        }
+
+        rule& operator=(rule const& rhs)
+        {
+            ptr = rhs.ptr;
+            name_ = rhs.name_;
+            return *this;
+        }
+
+        template <typename Expr>
+        rule& operator=(Expr const& xpr)
+        {
+            typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+            // report invalid expression error as early as possible
+            BOOST_MPL_ASSERT_MSG(
+                is_component::value,
+                xpr_is_not_convertible_to_a_parser, ());
+
+            define(xpr, mpl::false_());
+            return *this;
+        }
+
+        template <typename Expr>
+        friend rule& operator%=(rule& r, Expr const& xpr)
+        {
+            typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+            // report invalid expression error as early as possible
+            //~ BOOST_MPL_ASSERT_MSG(
+                //~ is_component::value,
+                //~ xpr_is_not_convertible_to_a_parser, ());
+
+            // temp workaround for mpl problem
+            BOOST_STATIC_ASSERT(is_component::value);
+
+            r.define(xpr, mpl::true_());
+            return r;
+        }
+
+        self_type alias() const
+        {
+            self_type result;
+            result.define(*this, mpl::false_());
+            return result;
+        }
+
+        typename
+            make_nonterminal_holder<
+                nonterminal_object<self_type>
+              , self_type
+            >::type
+        copy() const
+        {
+            typename
+                make_nonterminal_holder<
+                    nonterminal_object<self_type>
+                  , self_type
+                >::type
+            result = {{*this}};
+            return result;
+        }
+
+        std::string const& name() const
+        {
+            return name_;
+        }
+
+        void name(std::string const& str)
+        {
+            name_ = str;
+        }
+
+    private:
+
+        template <typename Definition>
+        friend struct grammar;
+
+        friend struct detail::rule_decorator;
+
+        template <typename Expr, typename Auto>
+        void define(Expr const& xpr, Auto)
+        {
+            typedef typename
+                result_of::as_component<qi::domain, Expr>::type
+            component;
+            typedef
+                detail::virtual_component<
+                    Iterator
+                  , component
+                  , typename base_type::context_type
+                  , skipper_type
+                  , Auto
+                >
+            virtual_component;
+            ptr = new virtual_component(spirit::as_component(qi::domain(), xpr));
+        }
+
+        template <typename Iterator_, typename Context, typename Skipper>
+        bool parse(
+            Iterator_& first, Iterator_ const& last
+          , Context& context, Skipper const& skipper) const
+        {
+            return ptr->parse(first, last, context, skipper);
+        }
+
+        std::string what() const
+        {
+            if (name_.empty())
+            {
+                if (ptr)
+                {
+                    return "unnamed-rule";
+                }
+                else
+                {
+                    return "empty-rule";
+                }
+            }
+            else
+            {
+                return name_;
+            }
+        }
+
+        friend struct nonterminal_director;
+        pointer_type ptr;
+        std::string name_;
+    };
+
+    // Decoration support: create a new virtual component and link it as
+    // first element in the chain of virtual components associated with this
+    // rule. Returns the previous topmost virtual component in the chain.
+    // We provide support from 1 to 5 arguments.
+
+    namespace detail
+    {
+        struct rule_decorator
+        {
+            template <typename Decorator, typename Rule, typename A1>
+            typename Rule::pointer_type
+            static call(Rule& r, A1 const& a1)
+            {
+                typename Rule::pointer_type old (r.ptr);
+                r.ptr.reset(new Decorator(r.ptr, a1));
+                return old;
+            }
+
+            template <typename Decorator, typename Rule, typename A1, typename A2>
+            typename Rule::pointer_type
+            static call(Rule& r, A1 const& a1, A2 const& a2)
+            {
+                typename Rule::pointer_type old (r.ptr);
+                r.ptr.reset(new Decorator(r.ptr, a1, a2));
+                return old;
+            }
+
+            template <typename Decorator, typename Rule
+              , typename A1, typename A2, typename A3
+            >
+            typename Rule::pointer_type
+            static call(Rule& r
+              , A1 const& a1, A2 const& a2, A3 const& a3)
+            {
+                typename Rule::pointer_type old (r.ptr);
+                r.ptr.reset(new Decorator(r.ptr, a1, a2, a3));
+                return old;
+            }
+
+            template <typename Decorator, typename Rule
+              , typename A1, typename A2, typename A3, typename A4
+            >
+            typename Rule::pointer_type
+            static call(Rule& r
+              , A1 const& a1, A2 const& a2
+              , A3 const& a3, A4 const& a4)
+            {
+                typename Rule::pointer_type old (r.ptr);
+                r.ptr.reset(new Decorator(r.ptr, a1, a2, a3, a4));
+                return old;
+            }
+
+            template <typename Decorator, typename Rule
+              , typename A1, typename A2, typename A3, typename A4, typename A5
+            >
+            typename Rule::pointer_type
+            static call(Rule& r
+              , A1 const& a1, A2 const& a2
+              , A3 const& a3, A4 const& a4, A5 const& a5)
+            {
+                typename Rule::pointer_type old (r.ptr);
+                r.ptr.reset(new Decorator(r.ptr, a1, a2, a3, a4, a5));
+                return old;
+            }
+        };
+    }
+
+    template <typename Decorator
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename A1>
+    typename rule<Iterator, T0, T1, T2>::pointer_type
+    decorate(rule<Iterator, T0, T1, T2>& r
+      , A1 const& a1)
+    {
+        return detail::rule_decorator::
+            template call<Decorator>(r, a1);
+    }
+
+    template <typename Decorator
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename A1, typename A2
+    >
+    typename rule<Iterator, T0, T1, T2>::pointer_type
+    decorate(rule<Iterator, T0, T1, T2>& r
+      , A1 const& a1, A2 const& a2)
+    {
+        return detail::rule_decorator::
+            template call<Decorator>(r, a1, a2);
+    }
+
+    template <typename Decorator
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename A1, typename A2, typename A3
+    >
+    typename rule<Iterator, T0, T1, T2>::pointer_type
+    decorate(rule<Iterator, T0, T1, T2>& r
+      , A1 const& a1, A2 const& a2, A3 const& a3)
+    {
+        return detail::rule_decorator::
+            template call<Decorator>(r, a1, a2, a3);
+    }
+
+    template <typename Decorator
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename A1, typename A2, typename A3, typename A4
+    >
+    typename rule<Iterator, T0, T1, T2>::pointer_type
+    decorate(rule<Iterator, T0, T1, T2>& r
+      , A1 const& a1, A2 const& a2
+      , A3 const& a3, A4 const& a4)
+    {
+        return detail::rule_decorator::
+            template call<Decorator>(r, a1, a2, a3, a4);
+    }
+
+    template <typename Decorator
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename A1, typename A2, typename A3, typename A4, typename A5
+    >
+    typename rule<Iterator, T0, T1, T2>::pointer_type
+    decorate(rule<Iterator, T0, T1, T2>& r
+      , A1 const& a1, A2 const& a2
+      , A3 const& a3, A4 const& a4, A5 const& a5)
+    {
+        return detail::rule_decorator::
+            template call<Decorator>(r, a1, a2, a3, a4, a5);
+    }
+
+    // Error handling support
+    template <
+        error_handler_result action
+      , typename Iterator, typename T0, typename T1, typename T2
+      , typename F>
+    void on_error(rule<Iterator, T0, T1, T2>& r, F f)
+    {
+        typedef
+            rule<Iterator, T0, T1, T2>
+        rule_type;
+
+        typedef
+            detail::error_handler<
+                Iterator
+              , typename rule_type::base_type::context_type
+              , typename rule_type::skipper_type
+              , F
+              , action>
+        error_handler;
+        decorate<error_handler>(r, f);
+    }
+
+    // Error handling support when <action> is not
+    // specified. We will default to <fail>.
+    template <typename Iterator, typename T0, typename T1
+      , typename T2, typename F>
+    void on_error(rule<Iterator, T0, T1, T2>& r, F f)
+    {
+        on_error<fail>(r, f);
+    }
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // forward declaration only
+    template <typename Parser, typename Skipper>
+    struct skipper_is_compatible;
+    
+    // If the parser is a rule, then the skipper must be convertible to
+    // the skipper used with this rule. 
+    template <
+        typename Iterator, typename T0, typename T1, typename T2, 
+        typename Skipper
+    >
+    struct skipper_is_compatible<qi::rule<Iterator, T0, T1, T2>, Skipper>
+      : is_convertible<
+            Skipper, typename qi::rule<Iterator, T0, T1, T2>::skipper_type
+        >
+    {
+    };
+
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,15 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NUMERIC_FEB_05_2007_1231PM)
+#define BOOST_SPIRIT_NUMERIC_FEB_05_2007_1231PM
+
+#include <boost/spirit/home/qi/numeric/int.hpp>
+#include <boost/spirit/home/qi/numeric/uint.hpp>
+#include <boost/spirit/home/qi/numeric/real.hpp>
+#include <boost/spirit/home/qi/numeric/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,490 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    Copyright (c) 2006 Stephen Nutt
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_NUMERIC_UTILS_APR_17_2006_0816AM)
+#define SPIRIT_NUMERIC_UTILS_APR_17_2006_0816AM
+
+#include <boost/detail/iterator.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/char_class/ascii.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+
+#include <limits>
+#include <boost/limits.hpp>
+
+#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
+# define SPIRIT_NUMERICS_LOOP_UNROLL 3
+#endif
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  Traits class for radix specific number conversion
+    //
+    //      Test the validity of a single character:
+    //
+    //          template<typename Char> static bool is_valid(Char ch);
+    //
+    //      Convert a digit from character representation to binary
+    //      representation:
+    //
+    //          template<typename Char> static int digit(Char ch);
+    //
+    //      The maximum radix digits that can be represented without
+    //      overflow:
+    //
+    //          template<typename T> struct digits::value;
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <unsigned Radix>
+    struct radix_traits;
+
+    // Binary
+    template <>
+    struct radix_traits<2>
+    {
+        template<typename Char>
+        static bool is_valid(Char ch)
+        {
+            return ('0' == ch || '1' == ch);
+        }
+
+        template<typename Char>
+        static unsigned digit(Char ch)
+        {
+            return ch - '0';
+        }
+
+        template<typename T>
+        struct digits
+        {
+            typedef std::numeric_limits<T> numeric_limits_;
+            BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits);
+        };
+    };
+
+    // Octal
+    template <>
+    struct radix_traits<8>
+    {
+        template<typename Char>
+        static bool is_valid(Char ch)
+        {
+            return ch >= '0' && ch <= '7';
+        }
+
+        template<typename Char>
+        static unsigned digit(Char ch)
+        {
+            return ch - '0';
+        }
+
+        template<typename T>
+        struct digits
+        {
+            typedef std::numeric_limits<T> numeric_limits_;
+            BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 3);
+        };
+    };
+
+    // Decimal
+    template <>
+    struct radix_traits<10>
+    {
+        template<typename Char>
+        static bool is_valid(Char ch)
+        {
+            return ch >= '0' && ch <= '9';
+        }
+
+        template<typename Char>
+        static unsigned digit(Char ch)
+        {
+            return ch - '0';
+        }
+
+        template<typename T>
+        struct digits
+        {
+            typedef std::numeric_limits<T> numeric_limits_;
+            BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits10);
+        };
+    };
+
+    // Hexadecimal
+    template <>
+    struct radix_traits<16>
+    {
+        template<typename Char>
+        static bool is_valid(Char ch)
+        {
+            return (ch >= '0' && ch <= '9')
+            || (ch >= 'a' && ch <= 'f')
+            || (ch >= 'A' && ch <= 'F');
+        }
+
+        template<typename Char>
+        static unsigned digit(Char ch)
+        {
+            if (ch >= '0' && ch <= '9')
+                return ch - '0';
+            return spirit::char_class::ascii::tolower(ch) - 'a' + 10;
+        }
+
+        template<typename T>
+        struct digits
+        {
+            typedef std::numeric_limits<T> numeric_limits_;
+            BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 4);
+        };
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  positive_accumulator/negative_accumulator: Accumulator policies for
+    //  extracting integers. Use positive_accumulator if number is positive.
+    //  Use negative_accumulator if number is negative.
+    ///////////////////////////////////////////////////////////////////////////
+    template <unsigned Radix>
+    struct positive_accumulator
+    {
+        template <typename T, typename Char>
+        static void add(T& n, Char ch, mpl::false_) // unchecked add
+        {
+            const int digit = radix_traits<Radix>::digit(ch);
+            n = n * Radix + digit;
+        }
+
+        template <typename T, typename Char>
+        static bool add(T& n, Char ch, mpl::true_) // checked add
+        {
+            // Ensure n *= Radix will not overflow
+            static T const max = (std::numeric_limits<T>::max)();
+            static T const val = (max - 1) / Radix;
+            if (n > val)
+                return false;
+
+            n *= Radix;
+
+            // Ensure n += digit will not overflow
+            const int digit = radix_traits<Radix>::digit(ch);
+            if (n > max - digit)
+                return false;
+
+            n += digit;
+            return true;
+        }
+    };
+
+    template <unsigned Radix>
+    struct negative_accumulator
+    {
+        template <typename T, typename Char>
+        static void add(T& n, Char ch, mpl::false_) // unchecked subtract
+        {
+            const int digit = radix_traits<Radix>::digit(ch);
+            n = n * Radix - digit;
+        }
+
+        template <typename T, typename Char>
+        static bool add(T& n, Char ch, mpl::true_) // checked subtract
+        {
+            // Ensure n *= Radix will not underflow
+            static T const min = (std::numeric_limits<T>::min)();
+            static T const val = (min + 1) / T(Radix);
+            if (n < val)
+                return false;
+
+            n *= Radix;
+
+            // Ensure n -= digit will not underflow
+            int const digit = radix_traits<Radix>::digit(ch);
+            if (n < min + digit)
+                return false;
+
+            n -= digit;
+            return true;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Common code for extract_int::parse specializations
+    ///////////////////////////////////////////////////////////////////////////
+    template <unsigned Radix, typename Accumulator, int MaxDigits>
+    struct int_extractor
+    {
+        template <typename Char, typename T>
+        static bool
+        call(Char ch, std::size_t count, T& n, mpl::true_)
+        {
+            static std::size_t const
+                overflow_free = radix_traits<Radix>::template digits<T>::value - 1;
+
+            if (count < overflow_free)
+            {
+                Accumulator::add(n, ch, mpl::false_());
+            }
+            else
+            {
+                if (!Accumulator::add(n, ch, mpl::true_()))
+                    return false; //  over/underflow!
+            }
+            return true;
+        }
+
+        template <typename Char, typename T>
+        static bool
+        call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
+        {
+            // no need to check for overflow
+            Accumulator::add(n, ch, mpl::false_());
+            return true;
+        }
+
+        template <typename Char>
+        static bool
+        call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
+        {
+            return true;
+        }
+
+        template <typename Char, typename T>
+        static bool
+        call(Char ch, std::size_t count, T& n)
+        {
+            return call(ch, count, n
+              , mpl::bool_<
+                    (   (MaxDigits < 0)
+                    ||  (MaxDigits > radix_traits<Radix>::template digits<T>::value)
+                    )
+                  && std::numeric_limits<T>::is_modulo
+                >()
+            );
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  End of loop checking: check if the number of digits
+    //  being parsed exceeds MaxDigits. Note: if MaxDigits == -1
+    //  we don't do any checking.
+    ///////////////////////////////////////////////////////////////////////////
+    template <int MaxDigits>
+    struct check_max_digits
+    {
+        static bool
+        call(std::size_t count)
+        {
+            return count < MaxDigits; // bounded
+        }
+    };
+
+    template <>
+    struct check_max_digits<-1>
+    {
+        static bool
+        call(std::size_t /*count*/)
+        {
+            return true; // unbounded
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  extract_int: main code for extracting integers
+    ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data)                                   \
+        if (!check_max_digits<MaxDigits>::call(count + leading_zeros)           \
+            || it == last)                                                      \
+            break;                                                              \
+        ch = *it;                                                               \
+        if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val))     \
+            break;                                                              \
+        ++it;                                                                   \
+        ++count;                                                                \
+    /**/
+
+    template <
+        typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+      , typename Accumulator = positive_accumulator<Radix>
+      , bool Accumulate = false
+    >
+    struct extract_int
+    {
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Attribute& attr)
+        {
+            typedef radix_traits<Radix> radix_check;
+            typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
+            typedef typename
+                boost::detail::iterator_traits<Iterator>::value_type
+            char_type;
+
+            Iterator it = first;
+            std::size_t leading_zeros = 0;
+            if (!Accumulate)
+            {
+                // skip leading zeros
+                while (it != last && *it == '0')
+                {
+                    ++it;
+                    ++leading_zeros;
+                }
+            }
+
+            Attribute val = Accumulate ? attr : 0;
+            std::size_t count = 0;
+            char_type ch;
+
+            while (true)
+            {
+                BOOST_PP_REPEAT(
+                    SPIRIT_NUMERICS_LOOP_UNROLL
+                  , SPIRIT_NUMERIC_INNER_LOOP, _)
+            }
+
+            if (count + leading_zeros >= MinDigits)
+            {
+                attr = val;
+                first = it;
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Iterator>
+        static bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , unused_type)
+        {
+            T n = 0; // must calculate value to detect over/underflow
+            return parse_main(first, last, n);
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Attribute& attr)
+        {
+            return parse_main(first, last, attr);
+        }
+    };
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  extract_int: main code for extracting integers
+    //  common case where MinDigits == 1 and MaxDigits = -1
+    ///////////////////////////////////////////////////////////////////////////
+#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data)                                   \
+        if (it == last)                                                         \
+            break;                                                              \
+        ch = *it;                                                               \
+        if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val))     \
+            break;                                                              \
+        ++it;                                                                   \
+        ++count;                                                                \
+    /**/
+
+    template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
+    struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
+    {
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_main(
+            Iterator& first
+          , Iterator const& last
+          , Attribute& attr)
+        {
+            typedef radix_traits<Radix> radix_check;
+            typedef int_extractor<Radix, Accumulator, -1> extractor;
+            typedef typename
+                boost::detail::iterator_traits<Iterator>::value_type
+            char_type;
+
+            Iterator it = first;
+            std::size_t count = 0;
+            if (!Accumulate)
+            {
+                // skip leading zeros
+                while (it != last && *it == '0')
+                {
+                    ++it;
+                    ++count;
+                }
+
+                if (it == last)
+                {
+                    if (count == 0) // must have at least one digit
+                        return false;
+                    attr = 0;
+                    first = it;
+                    return true;
+                }
+            }
+
+            Attribute val = Accumulate ? attr : 0;
+            char_type ch = *it;
+
+            if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
+            {
+                if (count == 0) // must have at least one digit
+                    return false;
+                attr = val;
+                first = it;
+                return true;
+            }
+
+            count = 0;
+            ++it;
+            while (true)
+            {
+                BOOST_PP_REPEAT(
+                    SPIRIT_NUMERICS_LOOP_UNROLL
+                  , SPIRIT_NUMERIC_INNER_LOOP, _)
+            }
+
+            attr = val;
+            first = it;
+            return true;
+        }
+
+        template <typename Iterator>
+        static bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , unused_type)
+        {
+            T n = 0; // must calculate value to detect over/underflow
+            return parse_main(first, last, n);
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse(
+            Iterator& first
+          , Iterator const& last
+          , Attribute& attr)
+        {
+            return parse_main(first, last, attr);
+        }
+    };
+
+#undef SPIRIT_NUMERIC_INNER_LOOP
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/detail/real_impl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,214 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_REAL_IMPL_APR_18_2006_0901AM)
+#define SPIRIT_REAL_IMPL_APR_18_2006_0901AM
+
+#include <cmath>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi  { namespace detail
+{
+    namespace
+    {
+        template <typename T>
+        inline void
+        scale_number(T const& exp, T& n)
+        {
+            using namespace std;    // allow for ADL to find the correct overload
+            n *= pow(T(10), exp);
+        }
+
+        inline void
+        scale_number(unused_type /*exp*/, unused_type /*n*/)
+        {
+            // no-op for unused_type
+        }
+
+        template <typename T>
+        inline void
+        scale_number(T const& exp, int frac, T& n)
+        {
+            scale_number(exp - T(frac), n);
+        }
+
+        inline void
+        scale_number(unused_type /*exp*/, int /*frac*/, unused_type /*n*/)
+        {
+            // no-op for unused_type
+        }
+
+        template <typename T>
+        inline T
+        negate_number(bool neg, T const& n)
+        {
+            return neg ? -n : n;
+        }
+
+        inline unused_type
+        negate_number(bool /*neg*/, unused_type n)
+        {
+            // no-op for unused_type
+            return n;
+        }
+        
+        template <typename T>
+        inline bool
+        number_equal_to_one(T const& value)
+        {
+            return value == 1.0;
+        }
+
+        inline bool
+        number_equal_to_one(unused_type)
+        {
+            // no-op for unused_type
+            return false;
+        }
+    }
+
+    template <typename T, typename RealPolicies>
+    struct real_impl
+    {
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse(Iterator& first, Iterator const& last, Attribute& attr, 
+            RealPolicies const& p)
+        {
+            if (first == last)
+                return false;
+            Iterator save = first;
+
+            // Start by parsing the sign. neg will be true if
+            // we got a "-" sign, false otherwise.
+            bool neg = p.parse_sign(first, last);
+
+            // Now attempt to parse an integer
+            Attribute n = 0;
+            bool got_a_number = p.parse_n(first, last, n);
+
+            // If we did not get a number it might be a NaN, Inf or a leading 
+            // dot.
+            if (!got_a_number)
+            {
+                // Check whether the number to parse is a NaN or Inf
+                if (p.parse_nan(first, last, attr) ||
+                    p.parse_inf(first, last, attr))
+                {
+                    // If we got a negative sign, negate the number
+                    attr = negate_number(neg, attr);
+                    return true;    // got a NaN or Inf, return early
+                }
+                
+                // If we did not get a number and our policies do not
+                // allow a leading dot, fail and return early (no-match)
+                if (!p.allow_leading_dot)
+                {
+                    first = save;
+                    return false;
+                }
+            }
+            
+            bool e_hit = false;
+            int frac_digits = 0;
+
+            // Try to parse the dot ('.' decimal point)
+            if (p.parse_dot(first, last))
+            {
+                // We got the decimal point. Now we will try to parse
+                // the fraction if it is there. If not, it defaults
+                // to zero (0) only if we already got a number.
+                Iterator savef = first;
+                if (p.parse_frac_n(first, last, n))
+                {
+                    // Optimization note: don't compute frac_digits if T is
+                    // an unused_type. This should be optimized away by the compiler.
+                    if (!is_same<T, unused_type>::value)
+                        frac_digits = 
+                            static_cast<int>(std::distance(savef, first));
+                }
+                else if (!got_a_number || !p.allow_trailing_dot)
+                {
+                    // We did not get a fraction. If we still haven't got a
+                    // number and our policies do not allow a trailing dot,
+                    // return no-match.
+                    first = save;
+                    return false;
+                }
+
+                // Now, let's see if we can parse the exponent prefix
+                e_hit = p.parse_exp(first, last);
+            }
+            else
+            {
+                // No dot and no number! Return no-match.
+                if (!got_a_number)
+                {
+                    first = save;
+                    return false;
+                }
+
+                // If we must expect a dot and we didn't see an exponent
+                // prefix, return no-match.
+                e_hit = p.parse_exp(first, last);
+                if (p.expect_dot && !e_hit)
+                {
+                    first = save;
+                    return false;
+                }
+            }
+
+            if (e_hit)
+            {
+                // We got the exponent prefix. Now we will try to parse the
+                // actual exponent. It is an error if it is not there.
+                Attribute exp = 0;
+                if (p.parse_exp_n(first, last, exp))
+                {
+                    // Got the exponent value. Scale the number by
+                    // exp-frac_digits.
+                    scale_number(exp, frac_digits, n);
+                }
+                else
+                {
+                    // Oops, no exponent, return no-match.
+                    first = save;
+                    return false;
+                }
+            }
+            else if (frac_digits)
+            {
+                // No exponent found. Scale the number by -frac_digits.
+                scale_number(Attribute(-frac_digits), n);
+            }
+            else if (number_equal_to_one(n))
+            {
+                // There is a chance of having to parse one of the 1.0#... 
+                // styles some implementations use for representing NaN or Inf.
+
+                // Check whether the number to parse is a NaN or Inf
+                if (p.parse_nan(first, last, attr) ||
+                    p.parse_inf(first, last, attr))
+                {
+                    // If we got a negative sign, negate the number
+                    attr = negate_number(neg, attr);
+                    return true;    // got a NaN or Inf, return immediately
+                }
+            }
+            
+            // If we got a negative sign, negate the number
+            attr = negate_number(neg, n);
+
+            // Success!!!
+            return true;
+        }
+    };
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/int.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/int.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_INT_APR_17_2006_0830AM)
+#define BOOST_SPIRIT_INT_APR_17_2006_0830AM
+
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct int_parser
+    {
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& /*component*/
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+            return extract_int<T, Radix, MinDigits, MaxDigits>
+                ::call(first, last, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "integer";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,312 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0951AM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0951AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/spirit/home/qi/numeric/real_policies.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit
+{
+    namespace qi
+    {
+        template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+        struct int_tag;
+
+        template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+        struct uint_tag;
+
+        template <typename T, typename RealPolicies>
+        struct real_tag;
+    }
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct is_int_tag<qi::int_tag<T, Radix, MinDigits, MaxDigits>, qi::domain> 
+      : mpl::true_ {};
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct is_int_tag<qi::uint_tag<T, Radix, MinDigits, MaxDigits>, qi::domain> 
+      : mpl::true_ {};
+
+    template <typename T, typename RealPolicies>
+    struct is_real_tag<qi::real_tag<T, RealPolicies>, qi::domain> 
+      : mpl::true_ {};
+}}
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct int_parser;
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct uint_parser;
+
+    template <typename T, typename RealPolicies>
+    struct real_parser;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric tags
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct int_tag
+    {
+    };
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct uint_tag
+    {
+    };
+
+    template <typename T, typename RealPolicies>
+    struct real_tag
+    {
+        RealPolicies policies;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric specs
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename T = int
+      , unsigned Radix = 10
+      , unsigned MinDigits = 1
+      , int MaxDigits = -1
+    >
+    struct int_spec
+      : proto::terminal<
+            int_tag<T, Radix, MinDigits, MaxDigits>
+        >::type
+    {
+    };
+
+    template <
+        typename T = int
+      , unsigned Radix = 10
+      , unsigned MinDigits = 1
+      , int MaxDigits = -1
+    >
+    struct uint_spec
+      : proto::terminal<
+            uint_tag<T, Radix, MinDigits, MaxDigits>
+        >::type
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename T = double,
+        typename RealPolicies = real_policies<T>
+    >
+    struct real_spec
+      : proto::terminal<
+            real_tag<T, RealPolicies>
+        >::type
+    {
+    private:
+        typedef typename 
+            proto::terminal<real_tag<T, RealPolicies> >::type
+        base_type;
+
+        base_type make_tag(RealPolicies const& p) const
+        {
+            base_type xpr = {{p}};
+            return xpr;
+        }
+
+    public:
+        real_spec(RealPolicies const& p = RealPolicies())
+          : base_type(make_tag(p))
+        {}
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename RealPolicies>
+        struct real_policy
+        {
+            template <typename Tag>
+            static RealPolicies get(Tag) { return RealPolicies(); }
+
+            template <typename T>
+            static RealPolicies const& get(real_tag<T, RealPolicies> const& p) 
+            { return p.policies; }
+        };
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of an int tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_int_director;
+
+    template <>
+    struct extract_int_director<tag::bin>
+    {
+        typedef uint_parser<unsigned, 2, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::oct>
+    {
+        typedef uint_parser<unsigned, 8, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::hex>
+    {
+        typedef uint_parser<unsigned, 16, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::ushort>
+    {
+        typedef uint_parser<unsigned short, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::ulong>
+    {
+        typedef uint_parser<unsigned long, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::uint>
+    {
+        typedef uint_parser<unsigned int, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::short_>
+    {
+        typedef int_parser<short, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::long_>
+    {
+        typedef int_parser<long, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::int_>
+    {
+        typedef int_parser<int, 10, 1, -1> type;
+    };
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <>
+    struct extract_int_director<tag::ulong_long>
+    {
+        typedef uint_parser<unsigned long long, 10, 1, -1> type;
+    };
+
+    template <>
+    struct extract_int_director<tag::long_long>
+    {
+        typedef int_parser<long long, 10, 1, -1> type;
+    };
+#endif
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct extract_int_director<int_tag<T, Radix, MinDigits, MaxDigits> >
+    {
+        typedef int_parser<T, Radix, MinDigits, MaxDigits> type;
+    };
+
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct extract_int_director<uint_tag<T, Radix, MinDigits, MaxDigits> >
+    {
+        typedef uint_parser<T, Radix, MinDigits, MaxDigits> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a real tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_real_director;
+
+    template <>
+    struct extract_real_director<tag::float_>
+    {
+        typedef real_parser<float, real_policies<float> > type;
+    };
+
+    template <>
+    struct extract_real_director<tag::double_>
+    {
+        typedef real_parser<double, real_policies<double> > type;
+    };
+
+    template <>
+    struct extract_real_director<tag::long_double>
+    {
+        typedef real_parser<long double, real_policies<long double> > type;
+    };
+
+    template <typename T, typename RealPolicies>
+    struct extract_real_director<real_tag<T, RealPolicies> >
+    {
+        typedef real_parser<T, RealPolicies> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // numeric parser meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct int_meta_grammar
+      : meta_grammar::compose_empty<
+            proto::if_<is_int_tag<proto::_arg, qi::domain>()>
+          , qi::domain
+          , mpl::identity<extract_int_director<mpl::_> >
+        >
+    {};
+
+    struct real_meta_grammar
+      : meta_grammar::compose_single<
+            proto::if_<is_real_tag<proto::_arg, qi::domain>()>
+          , qi::domain
+          , mpl::identity<extract_real_director<mpl::_> >
+        >
+    {};
+
+    struct numeric_meta_grammar
+      : proto::or_<int_meta_grammar, real_meta_grammar>
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
+      : mpl::identity<numeric_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,111 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NUMERIC_UTILS_APR_17_2006_0830AM)
+#define BOOST_SPIRIT_NUMERIC_UTILS_APR_17_2006_0830AM
+
+#include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////
+    //  Extract the prefix sign (- or +), return true if a '-' was found
+    ///////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    inline bool
+    extract_sign(Iterator& first, Iterator const& last)
+    {
+        BOOST_ASSERT(first != last); // precondition
+
+        // Extract the sign
+        bool neg = *first == '-';
+        if (neg || (*first == '+'))
+        {
+            ++first;
+            return neg;
+        }
+        return false;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    // Low level unsigned integer parser
+    ///////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
+      , bool Accumulate = false>
+    struct extract_uint
+    {
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        template <typename Iterator, typename Attribute>
+        static bool call(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            typedef detail::extract_int<
+                T
+              , Radix
+              , MinDigits
+              , MaxDigits
+              , detail::positive_accumulator<Radix>
+              , Accumulate>
+            extract_type;
+
+            Iterator save = first;
+            if (!extract_type::parse(first, last, attr))
+            {
+                first = save;
+                return false;
+            }
+            return true;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////
+    // Low level signed integer parser
+    ///////////////////////////////////////////////////////////////////////
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct extract_int
+    {
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        template <typename Iterator, typename Attribute>
+        static bool call(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            if (first == last)
+                return false;
+
+            typedef detail::extract_int<
+                T, Radix, MinDigits, MaxDigits>
+            extract_pos_type;
+
+            typedef detail::extract_int<
+                T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
+            extract_neg_type;
+
+            Iterator save = first;
+            bool hit = extract_sign(first, last);
+            if (hit)
+                hit = extract_neg_type::parse(first, last, attr);
+            else
+                hit = extract_pos_type::parse(first, last, attr);
+
+            if (!hit)
+            {
+                first = save;
+                return false;
+            }
+            return true;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/real.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/real.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,60 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_REAL_APR_18_2006_0850AM)
+#define BOOST_SPIRIT_REAL_APR_18_2006_0850AM
+
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/numeric/real_policies.hpp>
+#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
+#include <boost/spirit/home/qi/numeric/detail/real_impl.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    namespace detail
+    {
+        template <typename RealPolicies>
+        struct real_policy;
+    }
+
+    template <
+        typename T = double,
+        typename RealPolicies = real_policies<T>
+    >
+    struct real_parser
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            RealPolicies const& p = detail::real_policy<RealPolicies>::get(
+                fusion::at_c<0>(component.elements));
+
+            qi::skip(first, last, skipper);
+            return detail::real_impl<T, RealPolicies>::parse(first, last, attr, p);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "real number";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/real_policies.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/real_policies.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,182 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(SPIRIT_REAL_POLICIES_APR_17_2006_1158PM)
+#define SPIRIT_REAL_POLICIES_APR_17_2006_1158PM
+
+#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
+#include <boost/spirit/home/qi/detail/string_parse.hpp>
+#include <boost/detail/iterator.hpp>                // boost::iterator_traits<>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Default (unsigned) real number policies
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct ureal_policies
+    {
+        // trailing dot policy suggested by Gustavo Guerra
+        static bool const allow_leading_dot = true;
+        static bool const allow_trailing_dot = true;
+        static bool const expect_dot = false;
+
+        template <typename Iterator>
+        static bool
+        parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
+        {
+            return false;
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_n(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            return extract_uint<T, 10, 1, -1>::call(first, last, attr);
+        }
+
+        template <typename Iterator>
+        static bool
+        parse_dot(Iterator& first, Iterator const& last)
+        {
+            if (first == last || *first != '.')
+                return false;
+            ++first;
+            return true;
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            return extract_uint<T, 10, 1, -1, true>::call(first, last, attr);
+        }
+
+        template <typename Iterator>
+        static bool
+        parse_exp(Iterator& first, Iterator const& last)
+        {
+            if (first == last || (*first != 'e' && *first != 'E'))
+                return false;
+            ++first;
+            return true;
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_exp_n(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            return extract_int<T, 10, 1, -1>::call(first, last, attr);
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  The parse_nan() and parse_inf() functions get called whenever:
+        //
+        //    - a number to parse does not start with a digit (after having 
+        //      successfully parsed an optional sign)
+        //
+        //  or
+        //
+        //    - after a floating point number of the value 1 (having no 
+        //      exponential part and a fractional part value of 0) has been 
+        //      parsed. 
+        //
+        //  The first call allows to recognize representations of NaN or Inf
+        //  starting with a non-digit character (such as NaN, Inf, QNaN etc.). 
+        //
+        //  The second call allows to recognize representation formats starting 
+        //  with a 1.0 (such as 1.0#QNAN or 1.0#INF etc.).
+        //
+        //  The functions should return true if a Nan or Inf has been found. In 
+        //  this case the attr should be set to the matched value (NaN or 
+        //  Inf). The optional sign will be automatically applied afterwards.
+        //
+        //  The default implementation below recognizes representations of NaN 
+        //  and Inf as mandated by the C99 Standard and as proposed for 
+        //  inclusion into the C++0x Standard: nan, nan(...), inf and infinity
+        //  (the matching is performed case-insensitively).
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_nan(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            if (first == last)
+                return false;   // end of input reached
+            
+            if (*first != 'n' && *first != 'N')
+                return false;   // not "nan"
+            
+            // nan[(...)] ?
+            if (detail::string_parse("nan", "NAN", first, last, unused))
+            {
+                if (*first == '(')
+                {
+                    // skip trailing (...) part
+                    Iterator i = first;
+
+                    while (++i != last && *i != ')')
+                        ;
+                    if (i == last)
+                        return false;     // no trailing ')' found, give up
+
+                    first = ++i;
+                }
+                attr = std::numeric_limits<T>::quiet_NaN();
+                return true;
+            }
+            return false;
+        }        
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_inf(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            if (first == last)
+                return false;   // end of input reached
+            
+            if (*first != 'i' && *first != 'I')
+                return false;   // not "inf"
+            
+            // inf or infinity ?
+            if (detail::string_parse("inf", "INF", first, last, unused)) 
+            {
+                // skip allowed 'inity' part of infinity
+                detail::string_parse("inity", "INITY", first, last, unused);
+                attr = std::numeric_limits<T>::infinity();
+                return true;
+            }
+            return false;
+        }        
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Default (signed) real number policies
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct real_policies : ureal_policies<T>
+    {
+        template <typename Iterator>
+        static bool
+        parse_sign(Iterator& first, Iterator const& last)
+        {
+            return extract_sign(first, last);
+        }
+    };
+
+    template <typename T>
+    struct strict_ureal_policies : ureal_policies<T>
+    {
+        static bool const expect_dot = true;
+    };
+
+    template <typename T>
+    struct strict_real_policies : real_policies<T>
+    {
+        static bool const expect_dot = true;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/numeric/uint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/numeric/uint.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,53 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(SPIRIT_UINT_APR_17_2006_0901AM)
+#define SPIRIT_UINT_APR_17_2006_0901AM
+
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
+    struct uint_parser
+    {
+        // check template parameter 'Radix' for validity
+        BOOST_MPL_ASSERT_MSG(
+            Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
+            not_supported_radix, ());
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& /*component*/
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+            return extract_uint<T, Radix, MinDigits, MaxDigits>
+                ::call(first, last, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "unsigned integer";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,24 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_OPERATOR_FEB_02_2007_0558PM)
+#define BOOST_SPIRIT_OPERATOR_FEB_02_2007_0558PM
+
+#include <boost/spirit/home/qi/operator/sequence.hpp>
+#include <boost/spirit/home/qi/operator/expect.hpp>
+#include <boost/spirit/home/qi/operator/alternative.hpp>
+#include <boost/spirit/home/qi/operator/sequential_or.hpp>
+#include <boost/spirit/home/qi/operator/permutation.hpp>
+#include <boost/spirit/home/qi/operator/difference.hpp>
+#include <boost/spirit/home/qi/operator/list.hpp>
+#include <boost/spirit/home/qi/operator/optional.hpp>
+#include <boost/spirit/home/qi/operator/kleene.hpp>
+#include <boost/spirit/home/qi/operator/plus.hpp>
+#include <boost/spirit/home/qi/operator/and_predicate.hpp>
+#include <boost/spirit/home/qi/operator/not_predicate.hpp>
+#include <boost/spirit/home/qi/operator/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/alternative.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/alternative.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,97 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ALTERNATIVE_FEB_05_2007_1153AM)
+#define SPIRIT_ALTERNATIVE_FEB_05_2007_1153AM
+
+#include <boost/spirit/home/qi/detail/alternative_function.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/as_variant.hpp>
+#include <boost/fusion/include/any.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/push_front.hpp>
+#include <boost/variant.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct alternative
+    {
+        template <typename T>
+        struct transform_child : mpl::identity<T> {};
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            // if the original attribute list does not contain any unused
+            // attributes it is used, otherwise a single unused_type is
+            // pushed to the front the list. This is to make sure that if
+            // there is an unused in the list it is the first one.
+            typedef typename
+                mpl::find_if<All, is_same<mpl::_, unused_type> >::type
+            unused_;
+
+            typedef typename
+                mpl::eval_if<
+                    is_same<unused_, typename mpl::end<All>::type>,
+                    mpl::identity<All>,
+                    fusion::result_of::push_front<Filtered, unused_type>
+                >::type
+            attribute_sequence;
+
+            // Ok, now make a variant over the attribute_sequence. It's
+            // a pity that make_variant_over does not support forward MPL
+            // sequences. We use our own conversion metaprogram (as_variant).
+            typedef typename
+                as_variant<attribute_sequence>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<alternative, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            detail::alternative_function<Iterator, Context, Skipper, Attribute>
+                f(first, last, context, skipper, attr);
+
+            // return true if *any* of the parsers succeed
+            return fusion::any(component.elements, f);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "alternatives[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/and_predicate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/and_predicate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,58 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM)
+#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct and_predicate
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            Iterator i = first;
+            return director::parse(
+                subject(component), i, last, context, skipper, unused);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "and-predicate[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/difference.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/difference.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,91 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_DIFFERENCE_FEB_11_2007_1250PM)
+#define SPIRIT_DIFFERENCE_FEB_11_2007_1250PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct difference
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::left<Component>::type
+            left_type;
+
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, left_type, Context, Iterator>::type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                result_of::right<Component>::type::director
+            rdirector;
+
+            // Unlike classic Spirit, with this version of difference, the rule
+            // lit("policeman") - "police" will always fail to match.
+
+            // Spirit2 does not count the matching chars while parsing and
+            // there is no reliable and fast way to check if the LHS matches
+            // more than the RHS.
+
+            // Try RHS first
+            Iterator start = first;
+            if (rdirector::parse(right(component), first, last, context, skipper, unused))
+            {
+                // RHS succeeds, we fail.
+                first = start;
+                return false;
+            }
+            // RHS fails, now try LHS
+            return ldirector::parse(left(component), first, last, context, skipper, attr);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "difference[";
+
+            typedef typename
+                result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                result_of::right<Component>::type::director
+            rdirector;
+
+            result += ldirector::what(left(component));
+            result += ", ";
+            result += rdirector::what(right(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/expect.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/expect.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,49 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_EXPECT_APRIL_29_2007_0445PM)
+#define SPIRIT_EXPECT_APRIL_29_2007_0445PM
+
+#include <boost/spirit/home/qi/operator/sequence_base.hpp>
+#include <boost/spirit/home/qi/detail/expect_function.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Iterator>
+    struct expectation_failure
+    {
+        Iterator first;
+        Iterator last;
+        std::string what;
+    };
+
+    struct expect : sequence_base<expect>
+    {
+        friend struct sequence_base<expect>;
+
+    private:
+
+        template <typename Iterator, typename Context, typename Skipper>
+        static detail::expect_function<
+            Iterator, Context, Skipper
+          , expectation_failure<Iterator> >
+        fail_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+        {
+            return detail::expect_function<
+                Iterator, Context, Skipper, expectation_failure<Iterator> >
+                (first, last, context, skipper);
+        }
+
+        static std::string what_()
+        {
+            return "expect[";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/kleene.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/kleene.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,85 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_KLEENE_JAN_07_2007_0818AM)
+#define SPIRIT_KLEENE_JAN_07_2007_0818AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct kleene
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<kleene, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, subject_type, Context, Iterator>::type
+            attr_type;
+            typedef typename subject_type::director director;
+
+            // create a value if Attribute is not unused_type
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>
+              , unused_type
+              , attr_type>::type
+            val;
+
+            while(
+                director::parse(
+                    subject(component)
+                  , first, last, context, skipper, val)
+                )
+            {
+                container::push_back(attr, val);
+            }
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "kleene[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/list.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,97 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
+#define SPIRIT_LIST_MARCH_24_2007_1031AM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct list
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<list, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                result_of::right<Component>::type::director
+            rdirector;
+
+            typename container::result_of::value<Attribute>::type val;
+            if (ldirector::parse(
+                    left(component)
+                  , first, last, context, skipper, val)
+                )
+            {
+                container::push_back(attr, val);
+                Iterator i = first;
+                while(
+                    rdirector::parse(
+                        right(component)
+                      , i, last, context, skipper, unused)
+                 && ldirector::parse(
+                        left(component)
+                      , i, last, context, skipper, val)
+                    )
+                {
+                    container::push_back(attr, val);
+                    first = i;
+                }
+                return true;
+            }
+            return false;
+        }
+
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "list[";
+
+            typedef typename
+                result_of::left<Component>::type::director
+            ldirector;
+
+            typedef typename
+                result_of::right<Component>::type::director
+            rdirector;
+
+            result += ldirector::what(left(component));
+            result += ", ";
+            result += rdirector::what(right(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,146 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0620PM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0620PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    struct sequence;
+    struct expect;
+    struct alternative;
+    struct sequential_or;
+    struct permutation;
+    struct difference;
+    struct list;
+    struct optional;
+    struct kleene;
+    struct plus;
+    struct and_predicate;
+    struct not_predicate;
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // operator meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+    struct binary_meta_grammar
+      : proto::or_<
+            // a >> b
+            meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::shift_right, sequence
+              , main_meta_grammar
+            >
+            // a + b
+          , meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::plus, sequence
+              , main_meta_grammar
+            >
+            // a > b
+          , meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::greater, expect
+              , main_meta_grammar
+            >
+            // a | b
+          , meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::bitwise_or, alternative
+              , main_meta_grammar
+            >
+            // a || b
+          , meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::logical_or, sequential_or
+              , main_meta_grammar
+            >
+            // a ^ b
+          , meta_grammar::binary_rule_flat<
+                qi::domain, proto::tag::bitwise_xor, permutation
+              , main_meta_grammar
+            >
+            // a - b
+          , meta_grammar::binary_rule<
+                qi::domain, proto::tag::minus, difference
+              , main_meta_grammar, main_meta_grammar
+            >
+            // a % b
+          , meta_grammar::binary_rule<
+                qi::domain, proto::tag::modulus, list
+              , main_meta_grammar, main_meta_grammar
+            >
+        >
+    {
+    };
+
+    struct unary_meta_grammar
+      : proto::or_<
+            // -a
+            meta_grammar::unary_rule<
+                qi::domain, proto::tag::negate, optional
+              , main_meta_grammar
+            >
+            // *a
+          , meta_grammar::unary_rule<
+                qi::domain, proto::tag::dereference, kleene
+              , main_meta_grammar
+            >
+            // +a
+          , meta_grammar::unary_rule<
+                qi::domain, proto::tag::posit, plus
+              , main_meta_grammar
+            >
+            // &a
+          , meta_grammar::unary_rule<
+                qi::domain, proto::tag::address_of, and_predicate
+              , main_meta_grammar
+            >
+            // !a
+          , meta_grammar::unary_rule<
+                qi::domain, proto::tag::logical_not, not_predicate
+              , main_meta_grammar
+            >
+        >
+    {
+    };
+
+    struct operator_meta_grammar
+      : proto::or_<
+            binary_meta_grammar
+          , unary_meta_grammar
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
+      : mpl::identity<operator_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/not_predicate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/not_predicate.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,58 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM)
+#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct not_predicate
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& /*attr*/)
+        {
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            Iterator i = first;
+            return !director::parse(
+                subject(component), i, last, context, skipper, unused);
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "not-predicate[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/optional.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/optional.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
+#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct optional
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef boost::optional<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<optional, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, subject_type, Context, Iterator>::type
+            attr_type;
+
+            typedef typename subject_type::director director;
+
+            // create a value if Attribute is not unused_type
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>
+              , unused_type
+              , attr_type>::type
+            val;
+
+            if (director::parse(
+                subject(component), first, last, context, skipper, val))
+            {
+                qi::detail::assign_to(val, attr);
+            }
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "optional[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/permutation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/permutation.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,96 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_PERMUTATION_OR_MARCH_13_2007_1145PM)
+#define SPIRIT_PERMUTATION_OR_MARCH_13_2007_1145PM
+
+#include <boost/spirit/home/qi/detail/permute_function.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/algorithm/any.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/optional.hpp>
+#include <boost/foreach.hpp>
+#include <boost/array.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct permutation
+    {
+        template <typename T>
+        struct transform_child
+        {
+            typedef boost::optional<T> type;
+        };
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            typedef
+                typename fusion::result_of::as_vector<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<permutation, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            detail::permute_function<Iterator, Context, Skipper>
+                f(first, last, context, skipper);
+
+            boost::array<
+                bool
+              , fusion::result_of::size<typename Component::elements_type>::value
+            >
+            slots;
+
+            BOOST_FOREACH(bool& taken, slots)
+            {
+                taken = false;
+            }
+
+            // We have a bool array 'slots' with one flag for each parser.
+            // permute_function sets the slot to true when the corresponding
+            // parser successful matches. We loop until there are no more
+            // successful parsers.
+
+            bool result = false;
+            f.taken = slots.begin();
+            while (spirit::any_ns(component.elements, attr, f))
+            {
+                f.taken = slots.begin();
+                result = true;
+            }
+            return result;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "permutation[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/plus.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/plus.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,92 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_PLUS_MARCH_13_2007_0127PM)
+#define SPIRIT_PLUS_MARCH_13_2007_0127PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/detail/container.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct plus
+    {
+        template <typename T>
+        struct build_attribute_container
+        {
+            typedef std::vector<T> type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_container<plus, Component, Iterator, Context>
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+            typedef typename
+                traits::attribute_of<
+                    qi::domain, subject_type, Context, Iterator>::type
+            attr_type;
+            typedef typename subject_type::director director;
+
+            // create a value if Attribute is not unused_type
+            typename mpl::if_<
+                is_same<typename remove_const<Attribute>::type, unused_type>
+              , unused_type
+              , attr_type>::type
+            val;
+
+            if (director::parse(
+                    subject(component)
+                  , first, last, context, skipper, val)
+                )
+            {
+                container::push_back(attr, val);
+                while(director::parse(
+                        subject(component)
+                      , first, last, context, skipper, val)
+                    )
+                {
+                    container::push_back(attr, val);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "plus[";
+
+            typedef typename
+                result_of::subject<Component>::type::director
+            director;
+
+            result += director::what(subject(component));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/sequence.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/sequence.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,38 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SEQUENCE_APR_22_2006_0811AM)
+#define SPIRIT_SEQUENCE_APR_22_2006_0811AM
+
+#include <boost/spirit/home/qi/operator/sequence_base.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct sequence : sequence_base<sequence>
+    {
+        friend struct sequence_base<sequence>;
+
+    private:
+
+        template <typename Iterator, typename Context, typename Skipper>
+        static detail::fail_function<Iterator, Context, Skipper>
+        fail_function(
+            Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper)
+        {
+            return detail::fail_function<Iterator, Context, Skipper>
+                (first, last, context, skipper);
+        }
+
+        static std::string what_()
+        {
+            return "sequence[";
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/sequence_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/sequence_base.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,90 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SEQUENCE_BASE_APR_22_2006_0811AM)
+#define SPIRIT_SEQUENCE_BASE_APR_22_2006_0811AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/algorithm/any_if.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/detail/values.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Derived>
+    struct sequence_base // this class is shared by sequence and expect
+    {
+        template <typename T>
+        struct transform_child : mpl::identity<T> {};
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            typedef
+                typename fusion::result_of::as_vector<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<
+                sequence_base<Derived>, Component, Iterator, Context
+            >
+        {
+        };
+
+        template <typename Iterator, typename Context>
+        struct attribute_not_unused
+        {
+            template <typename Component>
+            struct apply
+              : spirit::traits::is_not_unused<typename
+                    traits::attribute_of<
+                        qi::domain, Component, Context, Iterator>::type
+                > 
+            {};
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            Iterator iter = first;
+            typedef attribute_not_unused<Iterator, Context> predicate;
+
+            // return false if *any* of the parsers fail
+            if (spirit::any_if(
+                component.elements, attr
+              , Derived::fail_function(iter, last, context, skipper), predicate()))
+                return false;
+            first = iter;
+            return true;
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = Derived::what_();
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/operator/sequential_or.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/operator/sequential_or.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,75 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_SEQUENTIAL_OR_MARCH_12_2007_1130PM)
+#define SPIRIT_SEQUENTIAL_OR_MARCH_12_2007_1130PM
+
+#include <boost/spirit/home/qi/detail/pass_function.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/algorithm/any_ns.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/for_each.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct sequential_or
+    {
+        template <typename T>
+        struct transform_child
+        {
+            typedef boost::optional<T> type;
+        };
+
+        template <typename All, typename Filtered>
+        struct build_container
+        {
+            typedef
+                typename fusion::result_of::as_vector<Filtered>::type
+            type;
+        };
+
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute :
+            build_fusion_sequence<
+                sequential_or, Component, Iterator, Context
+            >
+        {
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::detail::pass_function<Iterator, Context, Skipper>
+                f(first, last, context, skipper);
+
+            // return true if *any* of the parsers succeed
+            // (we use the non-short-circuiting version: any_ns
+            // to force all elements to be tested)
+            return spirit::any_ns(component.elements, attr, f);
+        }
+
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            std::string result = "sequential-or[";
+            fusion::for_each(component.elements,
+                spirit::detail::what_function(result));
+            result += "]";
+            return result;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/parse.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/parse.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,166 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_PARSE_APR_16_2006_0442PM)
+#define BOOST_SPIRIT_PARSE_APR_16_2006_0442PM
+
+#include <boost/spirit/home/qi/meta_grammar.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+
+///////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+    // normally any skipper can be used with any parser
+    template <typename Parser, typename Skipper>
+    struct skipper_is_compatible : mpl::true_
+    {
+    };
+    
+    // If the parser is a rule or a grammar, then the skipper must be 
+    // convertible to the skipper used with this rule or grammar. The 
+    // corresponding specializations are defined in the files grammar.hpp and
+    // rule.hpp.
+}}}
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Iterator, typename Expr>
+    inline bool
+    parse(
+        Iterator& first
+      , Iterator last
+      , Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Iterator, Expr));
+
+        typedef typename result_of::as_component<qi::domain, Expr>::type component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+        return director::parse(c, first, last, unused, unused, unused);
+    }
+
+    template <typename Iterator, typename Expr, typename Attr>
+    inline bool
+    parse(
+        Iterator& first
+      , Iterator last
+      , Expr const& xpr
+      , Attr& attr)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Iterator, Expr, Attr));
+
+        typedef typename result_of::as_component<qi::domain, Expr>::type component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+        return director::parse(c, first, last, unused, unused, attr);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename Expr, typename Skipper>
+    inline bool
+    phrase_parse(
+        Iterator& first
+      , Iterator last
+      , Expr const& xpr
+      , Skipper const& skipper_)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> expr_is_component;
+        typedef spirit::traits::is_component<qi::domain, Skipper> skipper_is_component;
+
+        // report invalid expressions error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Iterator, Expr, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(
+            skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, (Iterator, Expr, Skipper));
+
+        typedef spirit::traits::skipper_is_compatible<Expr, Skipper>
+            skipper_is_compatible;
+            
+//         BOOST_MPL_ASSERT_MSG(
+//             skipper_is_compatible::value,
+//             skipper_is_not_compatible_with_parser, (Iterator, Expr, Skipper));
+        
+        typedef typename result_of::as_component<qi::domain, Expr>::type component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        typename result_of::as_component<qi::domain, Skipper>::type 
+            skipper = spirit::as_component(qi::domain(), skipper_);
+
+        if (!director::parse(c, first, last, unused, skipper, unused))
+            return false;
+
+        // do a final post-skip
+        skip(first, last, skipper);
+        return true;
+    }
+
+    template <typename Iterator, typename Expr, typename Attr, typename Skipper>
+    inline bool
+    phrase_parse(
+        Iterator& first
+      , Iterator last
+      , Expr const& xpr
+      , Attr& attr
+      , Skipper const& skipper_)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> expr_is_component;
+        typedef spirit::traits::is_component<qi::domain, Skipper> skipper_is_component;
+
+        // report invalid expressions error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, 
+            (Iterator, Expr, Attr, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(
+            skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, 
+            (Iterator, Expr, Attr, Skipper));
+
+        typedef spirit::traits::skipper_is_compatible<Expr, Skipper>
+            skipper_is_compatible;
+            
+        BOOST_MPL_ASSERT_MSG(
+            skipper_is_compatible::value,
+            skipper_is_not_compatible_with_parser, 
+            (Iterator, Expr, Attr, Skipper));
+        
+        typedef typename result_of::as_component<qi::domain, Expr>::type component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+
+        typename result_of::as_component<qi::domain, Skipper>::type 
+            skipper = spirit::as_component(qi::domain(), skipper_);
+
+        if (!director::parse(c, first, last, unused, skipper, attr))
+            return false;
+
+        // do a final post-skip
+        skip(first, last, skipper);
+        return true;
+    }
+    
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/qi/skip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/skip.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,34 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_SKIP_APR_16_2006_0625PM)
+#define BOOST_SPIRIT_SKIP_APR_16_2006_0625PM
+
+#include <boost/spirit/home/qi/meta_grammar.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{ 
+    ///////////////////////////////////////////////////////////////////////////
+    // Move the /first/ iterator to the first non-matching position
+    // given a skip-parser. The function is a no-op if unused_type is 
+    // passed as the skip-parser.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator, typename T>
+    inline void skip(Iterator& first, Iterator const& last, T const& skipper)
+    {
+        while (first != last && 
+               T::director::parse(skipper, first, last, unused, unused, unused))
+            ;
+    }
+
+    template <typename Iterator>
+    inline void skip(Iterator& first, Iterator const& last, unused_type)
+    {
+    }
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/stream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_STREAM_MAY_05_2007_1227PM)
+#define BOOST_SPIRIT_STREAM_MAY_05_2007_1227PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/stream/match_manip.hpp>
+#include <boost/spirit/home/qi/stream/stream.hpp>
+#include <boost/spirit/home/qi/stream/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/stream/detail/iterator_istream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream/detail/iterator_istream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,52 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boist.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
+#define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
+
+#include <boost/iostreams/stream.hpp>
+#include <boost/detail/iterator.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    struct iterator_source
+    {
+        typedef typename 
+            boost::detail::iterator_traits<Iterator>::value_type 
+        char_type;
+        typedef boost::iostreams::source_tag category;
+
+        iterator_source (Iterator& first_, Iterator const& last_)
+          : first(first_), last(last_)
+        {}
+        
+        // Read up to n characters from the input sequence into the buffer s, 
+        // returning the number of characters read, or -1 to indicate 
+        // end-of-sequence.
+        std::streamsize read (char_type* s, std::streamsize n) 
+        {
+            if (first == last)
+                return -1;
+        
+            std::streamsize bytes_read = 0;
+            while (n--) {
+                *s = *first;
+                ++s; ++bytes_read;
+                if (++first == last)
+                    break;
+            }
+            return bytes_read;
+        }
+        
+        Iterator& first;
+        Iterator const& last;
+    };
+
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,104 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boist Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boist.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1203PM)
+#define BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1203PM
+
+#include <boost/spirit/home/qi/parse.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+#include <iterator>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Expr, 
+        typename Attribute = unused_type const, 
+        typename Skipper = unused_type
+    >
+    struct match_manip 
+    {
+        match_manip(Expr const& xpr, Attribute& a, Skipper const& s) 
+          : expr(xpr), attr(a), skipper(s)
+        {}
+
+        Expr const& expr;
+        Attribute& attr;
+        Skipper const& skipper;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr> 
+    inline std::basic_istream<Char, Traits> & 
+    operator>> (std::basic_istream<Char, Traits> &is, 
+        match_manip<Expr> const& fm)
+    {
+        typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+        input_iterator f(is);
+        input_iterator l;
+        if (!qi::parse (f, l, fm.expr))
+        {
+            is.setstate(std::ios_base::failbit);
+        }
+        return is;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr, typename Attribute> 
+    inline std::basic_istream<Char, Traits> & 
+    operator>> (std::basic_istream<Char, Traits> &is, 
+        match_manip<Expr, Attribute> const& fm)
+    {
+        typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+        input_iterator f(is);
+        input_iterator l;
+        if (!qi::parse(f, l, fm.expr, fm.attr))
+        {
+            is.setstate(std::ios_base::failbit);
+        }
+        return is;
+    }
+    
+    template<typename Char, typename Traits, typename Expr, typename Skipper> 
+    inline std::basic_istream<Char, Traits> & 
+    operator>> (std::basic_istream<Char, Traits> &is, 
+        match_manip<Expr, unused_type, Skipper> const& fm)
+    {
+        typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+        input_iterator f(is);
+        input_iterator l;
+        if (!qi::phrase_parse(f, l, fm.expr, fm.skipper))
+        {
+            is.setstate(std::ios_base::failbit);
+        }
+        return is;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template<
+        typename Char, typename Traits, 
+        typename Expr, typename Attribute, typename Skipper
+    > 
+    inline std::basic_istream<Char, Traits> & 
+    operator>> (
+        std::basic_istream<Char, Traits> &is, 
+        match_manip<Expr, Attribute, Skipper> const& fm)
+    {
+        typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+        input_iterator f(is);
+        input_iterator l;
+        if (!qi::phrase_parse(f, l, fm.expr, fm.attr, fm.skipper))
+        {
+            is.setstate(std::ios_base::failbit);
+        }
+        return is;
+    }
+    
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/stream/match_manip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream/match_manip.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,112 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1202PM)
+#define BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1202PM
+
+#include <boost/spirit/home/qi/parse.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/enable_if.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    inline detail::match_manip<Expr>
+    match(Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Expr));
+
+        return qi::detail::match_manip<Expr>(xpr, unused, unused);
+    }
+
+    template <typename Expr, typename Attribute>
+    inline detail::match_manip<Expr, Attribute>
+    match(Expr const& xpr, Attribute& p)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Expr, Attribute));
+
+        return qi::detail::match_manip<Expr, Attribute>(xpr, p, unused);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr, typename Skipper>
+    inline detail::match_manip<Expr, unused_type const, Skipper>
+    phrase_match(Expr const& xpr, Skipper const& s)
+    {
+        typedef
+            spirit::traits::is_component<qi::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<qi::domain, Skipper>
+        skipper_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Expr, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, (Expr, Skipper));
+
+        return qi::detail::match_manip<Expr, unused_type const, Skipper>(
+            xpr, unused, s);
+    }
+
+    template <typename Expr, typename Attribute, typename Skipper>
+    inline detail::match_manip<Expr, Attribute, Skipper>
+    phrase_match(Expr const& xpr, Attribute& p, Skipper const& s)
+    {
+        typedef
+            spirit::traits::is_component<qi::domain, Expr>
+        expr_is_component;
+        typedef
+            spirit::traits::is_component<qi::domain, Skipper>
+        skipper_is_component;
+
+        // report invalid expression errors as early as possible
+        BOOST_MPL_ASSERT_MSG(expr_is_component::value,
+            xpr_is_not_convertible_to_a_parser, (Expr, Attribute, Skipper));
+
+        BOOST_MPL_ASSERT_MSG(skipper_is_component::value,
+            skipper_is_not_convertible_to_a_parser, (Expr, Attribute, Skipper));
+
+        return qi::detail::match_manip<Expr, Attribute, Skipper>(xpr, p, s);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char, typename Traits, typename Expr>
+    inline typename
+        enable_if<
+            spirit::traits::is_component<qi::domain, Expr>,
+            std::basic_istream<Char, Traits> &
+        >::type
+    operator>> (std::basic_istream<Char, Traits> &is, Expr& xpr)
+    {
+        typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+        input_iterator f(is);
+        input_iterator l;
+        if (!qi::parse (f, l, xpr))
+        {
+            is.setstate(std::ios_base::failbit);
+        }
+        return is;
+    }
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/qi/stream/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,134 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_MAY_05_2007_1230PM)
+#define BOOST_SPIRIT_META_GRAMMAR_MAY_05_2007_1230PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit 
+{
+    namespace qi
+    {
+        template <typename T, typename Char>
+        struct stream_tag;
+    }
+
+    template <typename T, typename Char>
+    struct is_stream_tag<qi::stream_tag<T, Char>, qi::domain> 
+      : mpl::true_ {};
+}}
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    /////////////////////////////////////////////////////////////////////////// 
+    template <typename Char, typename T>
+    struct any_stream;
+    
+    template <typename Char>
+    struct stream_director;
+    
+    struct main_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // stream tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Char>
+    struct stream_tag
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // stream specs
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Char = char>
+    struct typed_stream
+      : proto::terminal<stream_tag<T, Char> >::type
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director for a stream
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag>
+    struct extract_stream_director;
+    
+    template <>
+    struct extract_stream_director<tag::stream>
+    {
+        typedef any_stream<char> type;
+    };
+
+    template <>
+    struct extract_stream_director<tag::wstream>
+    {
+        typedef any_stream<wchar_t> type;
+    };
+
+    template <typename T, typename Char>
+    struct extract_stream_director<stream_tag<T, Char> >
+    {
+        typedef any_stream<Char, T> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // utility meta-grammar
+    ///////////////////////////////////////////////////////////////////////////
+    struct utility_meta_grammar :  
+        // stream, wstream
+        meta_grammar::compose_empty<    
+            proto::if_<
+                is_stream_tag<proto::_arg, qi::domain>()
+            >,
+            qi::domain,
+            mpl::identity<extract_stream_director<mpl::_> >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the Qi meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, utility_meta_grammar> 
+            >::type
+        >
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<
+            Expr,
+            typename enable_if<
+                proto::matches<Expr, utility_meta_grammar> 
+            >::type
+        >
+      : mpl::identity<utility_meta_grammar>
+    {
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/stream/stream.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/stream/stream.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,73 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM)
+#define BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/spirit/home/qi/detail/string_parse.hpp>
+#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
+#include <boost/spirit/home/qi/stream/detail/iterator_istream.hpp>
+#include <boost/spirit/home/support/detail/hold_any.hpp>
+
+#include <iosfwd>
+#include <sstream>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+    // overload the streaming operators for the unused_type
+    template <typename Char, typename Traits>
+    inline std::basic_istream<Char, Traits>&
+    operator>> (std::basic_istream<Char, Traits>& is, unused_type&)
+    {
+        return is;
+    }
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Char, typename T = spirit::hold_any>
+    struct any_stream
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& /*component*/
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef qi::detail::iterator_source<Iterator> source_device;
+            typedef boost::iostreams::stream<source_device> instream;
+
+            qi::skip(first, last, skipper);
+            instream in (first, last);
+            in >> attr;                       // use existing operator>>()
+            return in.good() || in.eof();
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "any-stream";
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,14 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_STRING_FEB_03_2007_0355PM)
+#define BOOST_SPIRIT_STRING_FEB_03_2007_0355PM
+
+#include <boost/spirit/home/qi/string/lit.hpp>
+#include <boost/spirit/home/qi/string/symbols.hpp>
+#include <boost/spirit/home/qi/string/meta_grammar.hpp>
+
+#endif
Added: trunk/boost/spirit/home/qi/string/detail/tst.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/detail/tst.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,404 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_TST_MARCH_09_2007_0905AM)
+#define BOOST_SPIRIT_TST_MARCH_09_2007_0905AM
+
+#include <boost/call_traits.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/foreach.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    // This file contains low level TST routines, not for
+    // public consumption.
+
+    template <typename Char, typename T>
+    struct tst_node
+    {
+        tst_node(Char id)
+          : id(id), data(0), lt(0), eq(0), gt(0)
+        {
+        }
+
+        template <typename Alloc>
+        static void
+        destruct_node(tst_node* p, Alloc* alloc)
+        {
+            if (p)
+            {
+                if (p->data)
+                    alloc->delete_data(p->data);
+                destruct_node(p->lt, alloc);
+                destruct_node(p->eq, alloc);
+                destruct_node(p->gt, alloc);
+                alloc->delete_node(p);
+            }
+        }
+
+        template <typename Alloc>
+        static tst_node*
+        clone_node(tst_node* p, Alloc* alloc)
+        {
+            if (p)
+            {
+                tst_node* clone = alloc->new_node(p->id);
+                if (p->data)
+                    clone->data = alloc->new_data(*p->data);
+                clone->lt = clone_node(p->lt, alloc);
+                clone->eq = clone_node(p->eq, alloc);
+                clone->gt = clone_node(p->gt, alloc);
+                return clone;
+            }
+            return 0;
+        }
+
+        template <typename Iterator, typename Filter>
+        static T*
+        find(tst_node* start, Iterator& first, Iterator last, Filter filter)
+        {
+            if (first == last)
+                return false;
+
+            Iterator i = first;
+            Iterator latest = first;
+            tst_node* p = start;
+            T* found = 0;
+
+            while (p && i != last)
+            {
+                typename
+                    boost::detail::iterator_traits<Iterator>::value_type
+                c = filter(*i); // filter only the input
+
+                if (c == p->id)
+                {
+                    if (p->data)
+                    {
+                        found = p->data;
+                        latest = i;
+                    }
+                    p = p->eq;
+                    i++;
+                }
+                else if (c < p->id)
+                {
+                    p = p->lt;
+                }
+                else
+                {
+                    p = p->gt;
+                }
+            }
+
+            if (found)
+                first = ++latest; // one past the last matching char
+            return found;
+        }
+
+        template <typename Iterator, typename Alloc>
+        static bool
+        add(
+            tst_node*& start
+          , Iterator first
+          , Iterator last
+          , typename boost::call_traits<T>::param_type val
+          , Alloc* alloc)
+        {
+            if (first == last)
+                return false;
+
+            tst_node** pp = &start;
+            while (true)
+            {
+                typename
+                    boost::detail::iterator_traits<Iterator>::value_type
+                c = *first;
+
+                if (*pp == 0)
+                    *pp = alloc->new_node(c);
+                tst_node* p = *pp;
+
+                if (c == p->id)
+                {
+                    if (++first == last)
+                    {
+                        if (p->data == 0)
+                        {
+                            p->data = alloc->new_data(val);
+                            return true;
+                        }
+                        return false;
+                    }
+                    pp = &p->eq;
+                }
+                else if (c < p->id)
+                {
+                    pp = &p->lt;
+                }
+                else
+                {
+                    pp = &p->gt;
+                }
+            }
+        }
+
+        template <typename Iterator, typename Alloc>
+        static void
+        remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
+        {
+            if (p == 0 || first == last)
+                return;
+
+            typename
+                boost::detail::iterator_traits<Iterator>::value_type
+            c = *first;
+
+            if (c == p->id)
+            {
+                if (++first == last)
+                {
+                    if (p->data)
+                    {
+                        alloc->delete_data(p->data);
+                        p->data = 0;
+                    }
+                }
+                remove(p->eq, first, last, alloc);
+            }
+            else if (c < p->id)
+            {
+                remove(p->lt, first, last, alloc);
+            }
+            else
+            {
+                remove(p->gt, first, last, alloc);
+            }
+
+            if (p->lt == 0 && p->eq == 0 && p->gt == 0)
+            {
+                alloc->delete_node(p);
+                p = 0;
+            }
+        }
+
+        template <typename F>
+        static void
+        for_each(tst_node* p, std::basic_string<Char> prefix, F f)
+        {
+            if (p)
+            {
+                for_each(p->lt, prefix, f);
+                std::basic_string<Char> s = prefix + p->id;
+                for_each(p->eq, s, f);
+                if (p->data)
+                    f(s, *p->data);
+                for_each(p->gt, prefix, f);
+            }
+        }
+
+        Char id;        // the node's identity character
+        T* data;        // optional data
+        tst_node* lt;   // left pointer
+        tst_node* eq;   // middle pointer
+        tst_node* gt;   // right pointer
+    };
+
+/*
+    template <typename Char, typename T>
+    struct tst
+    {
+        typedef Char char_type; // the character type
+        typedef T value_type; // the value associated with each entry
+        typedef tst_node<Char, T> tst_node;
+
+        tst()
+        {
+        }
+
+        ~tst()
+        {
+            // Nothing to do here.
+            // The pools do the right thing for us
+        }
+
+        tst(tst const& rhs)
+        {
+            copy(rhs);
+        }
+
+        tst& operator=(tst const& rhs)
+        {
+            return assign(rhs);
+        }
+
+        template <typename Iterator, typename Filter>
+        T* find(Iterator& first, Iterator last, Filter filter) const
+        {
+            if (first != last)
+            {
+                Iterator save = first;
+                typename map_type::const_iterator
+                    i = map.find(filter(*first++));
+                if (i == map.end())
+                {
+                    first = save;
+                    return 0;
+                }
+                if (T* p = detail::find(i->second.root, first, last, filter))
+                {
+                    return p;
+                }
+                return i->second.data;
+            }
+            return 0;
+        }
+
+        template <typename Iterator>
+        T* find(Iterator& first, Iterator last) const
+        {
+            return find(first, last, tst_pass_through());
+        }
+
+        template <typename Iterator>
+        bool add(
+            Iterator first
+          , Iterator last
+          , typename boost::call_traits<T>::param_type val)
+        {
+            if (first != last)
+            {
+                map_data x = {0, 0};
+                std::pair<typename map_type::iterator, bool>
+                    r = map.insert(std::pair<Char, map_data>(*first++, x));
+
+                if (first != last)
+                {
+                    return detail::add(r.first->second.root, first, last, val, this);
+                }
+                else
+                {
+                    if (r.first->second.data)
+                        return false;
+                    r.first->second.data = this->new_data(val);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Iterator>
+        void remove(Iterator first, Iterator last)
+        {
+            if (first != last)
+            {
+                typename map_type::iterator i = map.find(*first++);
+                if (i != map.end())
+                {
+                    if (first != last)
+                    {
+                        detail::remove(i->second.root, first, last, this);
+                    }
+                    else if (i->second.data)
+                    {
+                        this->delete_data(i->second.data);
+                        i->second.data = 0;
+                    }
+                    if (i->second.data == 0 && i->second.root == 0)
+                    {
+                        map.erase(i);
+                    }
+                }
+            }
+        }
+
+        void clear()
+        {
+            BOOST_FOREACH(typename map_type::value_type& x, map)
+            {
+                destruct_node(x.second.root, this);
+                if (x.second.data)
+                    this->delete_data(x.second.data);
+            }
+            map.clear();
+        }
+
+        template <typename F>
+        void for_each(F f) const
+        {
+            BOOST_FOREACH(typename map_type::value_type const& x, map)
+            {
+                std::basic_string<Char> s(1, x.first);
+                detail::for_each(x.second.root, s, f);
+                if (x.second.data)
+                    f(s, *x.second.data);
+            }
+        }
+
+        tst_node* new_node(Char id)
+        {
+            return node_pool.construct(id);
+        }
+
+        T* new_data(typename boost::call_traits<T>::param_type val)
+        {
+            return data_pool.construct(val);
+        }
+
+        void delete_node(tst_node* p)
+        {
+            node_pool.destroy(p);
+        }
+
+        void delete_data(T* p)
+        {
+            data_pool.destroy(p);
+        }
+
+    private:
+
+        struct map_data
+        {
+            tst_node* root;
+            T* data;
+        };
+
+        typedef unordered_map<Char, map_data> map_type;
+
+        void copy(tst const& rhs)
+        {
+            BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
+            {
+                map_data xx = {clone_node(x.second.root, this), 0};
+                if (x.second.data)
+                    xx.data = data_pool.construct(*x.second.data);
+                map[x.first] = xx;
+            }
+        }
+
+        tst& assign(tst const& rhs)
+        {
+            if (this != &rhs)
+            {
+                BOOST_FOREACH(typename map_type::value_type& x, map)
+                {
+                    destruct_node(x.second.root, this);
+                }
+                map.clear();
+                copy(rhs);
+            }
+            return *this;
+        }
+
+        map_type map;
+        object_pool<tst_node> node_pool;
+        object_pool<T> data_pool;
+    };
+*/
+}}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/string/lit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/lit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,200 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_LIT_APR_18_2006_1125PM)
+#define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/detail/string_parse.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/detail/to_narrow.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // parse literal strings
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct literal_string
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;   // literal parsers have no attribute
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+            return detail::string_parse(
+                fusion::at_c<0>(component.elements)
+              , first
+              , last
+              , attr
+            );
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("\"")
+                + spirit::detail::to_narrow_string(
+                    fusion::at_c<0>(component.elements))
+                + std::string("\"")
+            ;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // parse lazy strings
+    ///////////////////////////////////////////////////////////////////////////
+    struct lazy_string
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type
+            subject_type;
+
+            typedef typename
+                remove_reference<
+                    typename boost::result_of<subject_type(unused_type, Context)>::type
+                >::type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& context, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+            return detail::string_parse(
+                fusion::at_c<0>(component.elements)(unused, context)
+              , first
+              , last
+              , attr
+            );
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "string";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case literal_string version
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct no_case_literal_string
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef unused_type type;   // literal parsers have no attribute
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            qi::skip(first, last, skipper);
+            return detail::string_parse(
+                fusion::at_c<0>(component.elements)
+              , fusion::at_c<1>(component.elements)
+              , first
+              , last
+              , attr
+            );
+        }
+
+        template <typename Component>
+        static std::string what(Component const& component)
+        {
+            return std::string("case-insensitive \"")
+                + spirit::detail::to_narrow_string(
+                    fusion::at_c<0>(component.elements))
+                + std::string("\"")
+            ;
+        }
+    };
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // no_case_literal_string generator
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Elements, typename Modifier, typename Char
+    >
+    struct make_modified_component<
+        Domain, qi::literal_string<Char>, Elements, Modifier
+      , typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
+        >::type
+    >
+    {
+        typedef std::basic_string<Char> string_type;
+        typedef fusion::vector<string_type, string_type> vector_type;
+        typedef
+            component<qi::domain, qi::no_case_literal_string<Char>, vector_type>
+        type;
+
+        static type
+        call(Elements const& elements)
+        {
+            typedef typename Modifier::char_set char_set;
+
+            Char const* in = fusion::at_c<0>(elements);
+            string_type lo(in);
+            string_type hi(in);
+
+            typename string_type::iterator loi = lo.begin();
+            typename string_type::iterator hii = hi.begin();
+
+            for (; loi != lo.end(); ++loi, ++hii, ++in)
+            {
+                *loi = char_set::tolower(*loi);
+                *hii = char_set::toupper(*hii);
+            }
+
+            return type(vector_type(lo, hi));
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/string/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,203 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_03_2007_0356PM)
+#define BOOST_SPIRIT_META_GRAMMAR_FEB_03_2007_0356PM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/support/placeholders.hpp>
+#include <boost/spirit/home/support/meta_grammar.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace qi
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // forwards
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename Char>
+    struct literal_string;
+
+    struct lazy_string;
+
+    template <typename Filter>
+    struct symbols_director;
+
+    struct string_meta_grammar;
+
+    template <typename Expr, typename Enable>
+    struct is_valid_expr;
+
+    template <typename Expr, typename Enable>
+    struct expr_transform;
+
+    template <typename Lookup>
+    struct symbols_lookup;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // get the director of a string literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct extract_char;
+
+    template <typename Char, typename Traits, typename Alloc>
+    struct extract_char<std::basic_string<Char, Traits, Alloc> >
+    {
+        typedef Char type;
+    };
+
+    template <typename Char, int N>
+    struct extract_char<Char[N]>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    template <typename Char, int N>
+    struct extract_char<Char(&)[N]>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    template <typename Char>
+    struct extract_char<Char*>
+    {
+        typedef typename remove_const<Char>::type type;
+    };
+
+    template <typename Tag, typename T>
+    struct extract_lit_director;
+
+    template <typename T>
+    struct extract_lit_director<tag::lit, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef literal_string<char_type> type;
+    };
+
+    template <typename T>
+    struct extract_lit_director<tag::wlit, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef literal_string<char_type> type;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // string parser meta-grammars
+    ///////////////////////////////////////////////////////////////////////////
+
+    // literal strings: "hello"
+    struct string_literal_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                qi::domain, char const*, literal_string<char> >
+          , meta_grammar::terminal_rule<
+                qi::domain, char*, literal_string<char> >
+          , meta_grammar::terminal_rule<
+                qi::domain, wchar_t const*, literal_string<wchar_t> >
+          , meta_grammar::terminal_rule<
+                qi::domain, wchar_t*, literal_string<wchar_t> >
+
+        >
+    {
+    };
+
+    // literal strings: "hello"
+    struct basic_string_literal_meta_grammar
+      : proto::or_<
+            proto::terminal<char const*>
+          , proto::terminal<wchar_t const*>
+        >
+    {
+    };
+
+    // std::string(s)
+    struct basic_std_string_meta_grammar
+      : proto::or_<
+            proto::terminal<std::basic_string<char, proto::_, proto::_> >
+          , proto::terminal<std::basic_string<wchar_t, proto::_, proto::_> >
+        >
+    {
+    };
+
+    // std::string(s)
+    struct std_string_meta_grammar
+      : proto::or_<
+            meta_grammar::terminal_rule<
+                qi::domain
+              , std::basic_string<char, proto::_, proto::_>
+              , literal_string<char> >
+          , meta_grammar::terminal_rule<
+                qi::domain
+              , std::basic_string<wchar_t, proto::_, proto::_>
+              , literal_string<wchar_t> >
+        >
+    {
+    };
+
+    namespace detail
+    {
+        // we use this test to detect if the argument to lit is a callable
+        // function or not. Only types convertible to int or function/
+        // function objects are allowed. Therefore, if T is not convertible
+        // to an int, then we have a function/function object.
+        template <typename T>
+        struct is_not_convertible_to_int
+          : mpl::not_<is_convertible<T, int> >
+        {};
+    }
+
+    // strings: "hello", lit("hello"), lit(str), lit(f), symbols
+    struct string_meta_grammar
+      : proto::or_<
+            string_literal_meta_grammar
+          , std_string_meta_grammar
+          , meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_lit_tag<proto::_arg, qi::domain>()>
+                  , proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
+                >
+              , qi::domain
+              , mpl::identity<extract_lit_director<mpl::_, mpl::_> >
+            >
+          , meta_grammar::function1_rule<
+                qi::domain
+              , tag::lit
+              , lazy_string
+              , proto::if_<
+                    detail::is_not_convertible_to_int<proto::_arg >() >
+            >
+          , meta_grammar::terminal_rule<
+                qi::domain
+              , symbols_lookup<proto::_>
+              , symbols_director<>
+            >
+        >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  These specializations non-intrusively hooks into the RD meta-grammar.
+    //  (see qi/meta_grammar.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Expr>
+    struct is_valid_expr<Expr
+      , typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
+      : mpl::true_
+    {
+    };
+
+    template <typename Expr>
+    struct expr_transform<Expr
+      , typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
+      : mpl::identity<string_meta_grammar>
+    {
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/string/symbols.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/symbols.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,297 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_SYMBOL_MARCH_11_2007_1055AM)
+#define BOOST_SPIRIT_SYMBOL_MARCH_11_2007_1055AM
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/skip.hpp>
+#include <boost/spirit/home/qi/string/tst.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/range.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#endif
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Filter = tst_pass_through>
+    struct symbols_director
+    {
+        template <typename Component, typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef typename
+                result_of::subject<Component>::type::ptr_type::element_type::value_type
+            type;
+        };
+
+        template <
+            typename Component
+          , typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        static bool parse(
+            Component const& component
+          , Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr)
+        {
+            typedef typename
+                result_of::subject<Component>::type::ptr_type::element_type::value_type
+            value_type;
+
+            qi::skip(first, last, skipper);
+
+            if (value_type* val_ptr
+                = fusion::at_c<0>(component.elements)
+                    .lookup->find(first, last, Filter()))
+            {
+                detail::assign_to(*val_ptr, attr);
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            // perhaps we should show some of the contents?
+            return "symbols";
+        }
+    };
+
+    template <typename Lookup>
+    struct symbols_lookup
+    {
+        typedef shared_ptr<Lookup> ptr_type;
+        ptr_type lookup;
+    };
+
+    template <typename Char, typename T, typename Lookup = tst<Char, T> >
+    struct symbols
+      : proto::extends<
+            typename proto::terminal<symbols_lookup<Lookup> >::type
+          , symbols<Char, T>
+        >
+    {
+        typedef Char char_type; // the character type
+        typedef T value_type; // the value associated with each entry
+        typedef shared_ptr<Lookup> ptr_type;
+
+        symbols()
+          : add(*this)
+          , remove(*this)
+        {
+            proto::arg(*this).lookup = ptr_type(new Lookup());
+        }
+
+        template <typename Symbols>
+        symbols(Symbols const& syms)
+          : add(*this)
+          , remove(*this)
+        {
+            proto::arg(*this).lookup = ptr_type(new Lookup());
+            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
+            while (si != boost::end(syms))
+                add(*si++);
+        }
+
+        template <typename Symbols, typename Data>
+        symbols(Symbols const& syms, Data const& data)
+          : add(*this)
+          , remove(*this)
+        {
+            proto::arg(*this).lookup = ptr_type(new Lookup());
+            typename range_const_iterator<Symbols>::type si = boost::begin(syms);
+            typename range_const_iterator<Data>::type di = boost::begin(data);
+            while (si != boost::end(syms))
+                add(*si++, *di++);
+        }
+
+        symbols&
+        operator=(symbols const& rhs)
+        {
+            proto::arg(*this) = proto::arg(rhs);
+            return *this;
+        }
+
+        void clear()
+        {
+            lookup()->clear();
+        }
+
+        struct adder;
+        struct remover;
+
+        adder const&
+        operator=(Char const* str)
+        {
+            lookup()->clear();
+            return add(str);
+        }
+
+        adder const&
+        operator+=(Char const* str)
+        {
+            return add(str);
+        }
+
+        remover const&
+        operator-=(Char const* str)
+        {
+            return remove(str);
+        }
+
+        ptr_type lookup() const
+        {
+            return proto::arg(*this).lookup;
+        }
+
+        template <typename F>
+        void for_each(F f) const
+        {
+            lookup()->for_each(f);
+        }
+
+        struct adder
+        {
+            template <typename, typename = unused_type, typename = unused_type>
+            struct result { typedef adder const& type; };
+
+            adder(symbols& sym)
+              : sym(sym)
+            {
+            }
+
+            template <typename Iterator>
+            adder const&
+            operator()(Iterator const& first, Iterator const& last, T const& val = T()) const
+            {
+                sym.lookup()->add(first, last, val);
+                return *this;
+            }
+
+            adder const&
+            operator()(Char const* s, T const& val = T()) const
+            {
+                Char const* last = s;
+                while (*last)
+                    last++;
+                sym.lookup()->add(s, last, val);
+                return *this;
+            }
+
+            adder const&
+            operator,(Char const* s) const
+            {
+                Char const* last = s;
+                while (*last)
+                    last++;
+                sym.lookup()->add(s, last, T());
+                return *this;
+            }
+
+            symbols& sym;
+        };
+
+        struct remover
+        {
+            template <typename, typename = unused_type, typename = unused_type>
+            struct result { typedef adder const& type; };
+
+            remover(symbols& sym)
+              : sym(sym)
+            {
+            }
+
+            template <typename Iterator>
+            remover const&
+            operator()(Iterator const& first, Iterator const& last) const
+            {
+                sym.lookup()->remove(first, last);
+                return *this;
+            }
+
+            remover const&
+            operator()(Char const* s) const
+            {
+                Char const* last = s;
+                while (*last)
+                    last++;
+                sym.lookup()->remove(s, last);
+                return *this;
+            }
+
+            remover const&
+            operator,(Char const* s) const
+            {
+                Char const* last = s;
+                while (*last)
+                    last++;
+                sym.lookup()->remove(s, last);
+                return *this;
+            }
+
+            symbols& sym;
+        };
+
+        adder add;
+        remover remove;
+    };
+}}}
+
+
+namespace boost { namespace spirit { namespace traits
+{
+    namespace detail
+    {
+        template <typename CharSet>
+        struct no_case_filter
+        {
+            template <typename Char>
+            Char operator()(Char ch) const
+            {
+                return CharSet::tolower(ch);
+            }
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // generator for no-case symbols
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Elements, typename Modifier>
+    struct make_modified_component<Domain, qi::symbols_director<>, Elements, Modifier
+      , typename enable_if<
+            is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
+        >::type
+    >
+    {
+        typedef detail::no_case_filter<typename Modifier::char_set> filter;
+        typedef component<qi::domain, qi::symbols_director<filter>, Elements> type;
+
+        static type
+        call(Elements const& elements)
+        {
+            // we return the same lookup but this time we use a director
+            // with a filter that converts to lower-case.
+            return elements;
+        }
+    };
+}}}
+
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/qi/string/tst.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/tst.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,133 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_TST_JUNE_03_2007_1031AM)
+#define BOOST_SPIRIT_TST_JUNE_03_2007_1031AM
+
+#include <boost/spirit/home/qi/string/detail/tst.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct tst_pass_through
+    {
+        template <typename Char>
+        Char operator()(Char ch) const
+        {
+            return ch;
+        }
+    };
+
+    template <typename Char, typename T>
+    struct tst
+    {
+        typedef Char char_type; // the character type
+        typedef T value_type; // the value associated with each entry
+        typedef detail::tst_node<Char, T> node;
+
+        tst()
+          : root(0)
+        {
+        }
+
+        ~tst()
+        {
+            clear();
+        }
+
+        tst(tst const& rhs)
+          : root(0)
+        {
+            copy(rhs);
+        }
+
+        tst& operator=(tst const& rhs)
+        {
+            return assign(rhs);
+        }
+
+        template <typename Iterator, typename Filter>
+        T* find(Iterator& first, Iterator last, Filter filter) const
+        {
+            return node::find(root, first, last, filter);
+        }
+
+        template <typename Iterator>
+        T* find(Iterator& first, Iterator last) const
+        {
+            return find(first, last, tst_pass_through());
+        }
+
+        template <typename Iterator>
+        bool add(
+            Iterator first
+          , Iterator last
+          , typename boost::call_traits<T>::param_type val)
+        {
+            return node::add(root, first, last, val, this);
+        }
+
+        template <typename Iterator>
+        void remove(Iterator first, Iterator last)
+        {
+            node::remove(root, first, last, this);
+        }
+
+        void clear()
+        {
+            node::destruct_node(root, this);
+            root = 0;
+        }
+
+        template <typename F>
+        void for_each(F f) const
+        {
+            node::for_each(root, "", f);
+        }
+
+    private:
+
+        friend struct detail::tst_node<Char, T>;
+
+        void copy(tst const& rhs)
+        {
+            root = node::clone_node(rhs.root, this);
+        }
+
+        tst& assign(tst const& rhs)
+        {
+            if (this != &rhs)
+            {
+                clear();
+                copy(rhs);
+            }
+            return *this;
+        }
+
+        node* root;
+
+        node* new_node(Char id)
+        {
+            return new node(id);
+        }
+
+        T* new_data(typename boost::call_traits<T>::param_type val)
+        {
+            return new T(val);
+        }
+
+        void delete_node(node* p)
+        {
+            delete p;
+        }
+
+        void delete_data(T* p)
+        {
+            delete p;
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/string/tst_map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/string/tst_map.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,211 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM)
+#define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
+
+#include <boost/spirit/home/qi/string/detail/tst.hpp>
+#include <boost/spirit/home/support/detail/unordered_map.hpp>
+#include <boost/pool/object_pool.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    struct tst_pass_through; // declared in tst.hpp
+
+    template <typename Char, typename T>
+    struct tst_map
+    {
+        typedef Char char_type; // the character type
+        typedef T value_type; // the value associated with each entry
+        typedef detail::tst_node<Char, T> node;
+
+        tst_map()
+        {
+        }
+
+        ~tst_map()
+        {
+            // Nothing to do here.
+            // The pools do the right thing for us
+        }
+
+        tst_map(tst_map const& rhs)
+        {
+            copy(rhs);
+        }
+
+        tst_map& operator=(tst_map const& rhs)
+        {
+            return assign(rhs);
+        }
+
+        template <typename Iterator, typename Filter>
+        T* find(Iterator& first, Iterator last, Filter filter) const
+        {
+            if (first != last)
+            {
+                Iterator save = first;
+                typename map_type::const_iterator
+                    i = map.find(filter(*first++));
+                if (i == map.end())
+                {
+                    first = save;
+                    return 0;
+                }
+                if (T* p = node::find(i->second.root, first, last, filter))
+                {
+                    return p;
+                }
+                return i->second.data;
+            }
+            return 0;
+        }
+
+        template <typename Iterator>
+        T* find(Iterator& first, Iterator last) const
+        {
+            return find(first, last, tst_pass_through());
+        }
+
+        template <typename Iterator>
+        bool add(
+            Iterator first
+          , Iterator last
+          , typename boost::call_traits<T>::param_type val)
+        {
+            if (first != last)
+            {
+                map_data x = {0, 0};
+                std::pair<typename map_type::iterator, bool>
+                    r = map.insert(std::pair<Char, map_data>(*first++, x));
+
+                if (first != last)
+                {
+                    return node::add(r.first->second.root, first, last, val, this);
+                }
+                else
+                {
+                    if (r.first->second.data)
+                        return false;
+                    r.first->second.data = this->new_data(val);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Iterator>
+        void remove(Iterator first, Iterator last)
+        {
+            if (first != last)
+            {
+                typename map_type::iterator i = map.find(*first++);
+                if (i != map.end())
+                {
+                    if (first != last)
+                    {
+                        node::remove(i->second.root, first, last, this);
+                    }
+                    else if (i->second.data)
+                    {
+                        this->delete_data(i->second.data);
+                        i->second.data = 0;
+                    }
+                    if (i->second.data == 0 && i->second.root == 0)
+                    {
+                        map.erase(i);
+                    }
+                }
+            }
+        }
+
+        void clear()
+        {
+            BOOST_FOREACH(typename map_type::value_type& x, map)
+            {
+                node::destruct_node(x.second.root, this);
+                if (x.second.data)
+                    this->delete_data(x.second.data);
+            }
+            map.clear();
+        }
+
+        template <typename F>
+        void for_each(F f) const
+        {
+            BOOST_FOREACH(typename map_type::value_type const& x, map)
+            {
+                std::basic_string<Char> s(1, x.first);
+                node::for_each(x.second.root, s, f);
+                if (x.second.data)
+                    f(s, *x.second.data);
+            }
+        }
+
+    private:
+
+        friend struct detail::tst_node<Char, T>;
+
+        struct map_data
+        {
+            node* root;
+            T* data;
+        };
+
+        typedef unordered_map<Char, map_data> map_type;
+
+        void copy(tst_map const& rhs)
+        {
+            BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
+            {
+                map_data xx = {node::clone_node(x.second.root, this), 0};
+                if (x.second.data)
+                    xx.data = data_pool.construct(*x.second.data);
+                map[x.first] = xx;
+            }
+        }
+
+        tst_map& assign(tst_map const& rhs)
+        {
+            if (this != &rhs)
+            {
+                BOOST_FOREACH(typename map_type::value_type& x, map)
+                {
+                    node::destruct_node(x.second.root, this);
+                }
+                map.clear();
+                copy(rhs);
+            }
+            return *this;
+        }
+
+        node* new_node(Char id)
+        {
+            return node_pool.construct(id);
+        }
+
+        T* new_data(typename boost::call_traits<T>::param_type val)
+        {
+            return data_pool.construct(val);
+        }
+
+        void delete_node(node* p)
+        {
+            node_pool.destroy(p);
+        }
+
+        void delete_data(T* p)
+        {
+            data_pool.destroy(p);
+        }
+
+        map_type map;
+        object_pool<node> node_pool;
+        object_pool<T> data_pool;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/qi/what.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/what.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,34 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_WHAT_APRIL_21_2007_0732AM)
+#define BOOST_SPIRIT_WHAT_APRIL_21_2007_0732AM
+
+#include <boost/spirit/home/qi/meta_grammar.hpp>
+#include <boost/mpl/assert.hpp>
+#include <string>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Expr>
+    inline std::string what(Expr const& xpr)
+    {
+        typedef spirit::traits::is_component<qi::domain, Expr> is_component;
+
+        // report invalid expression error as early as possible
+        BOOST_MPL_ASSERT_MSG(
+            is_component::value,
+            xpr_is_not_convertible_to_a_parser, ());
+
+        typedef typename result_of::as_component<qi::domain, Expr>::type component;
+        typedef typename component::director director;
+        component c = spirit::as_component(qi::domain(), xpr);
+        return director::what(c);
+    }
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/algorithm/any.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/algorithm/any.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,72 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ANY_APR_22_2006_1147AM)
+#define BOOST_SPIRIT_ANY_APR_22_2006_1147AM
+
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/fusion/include/next.hpp>
+#include <boost/fusion/include/deref.hpp>
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/any.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit
+{
+    // This is the binary version of fusion::any. This might
+    // be a good candidate for inclusion in fusion algorithm
+
+    namespace detail
+    {
+        template <typename First1, typename Last, typename First2, typename F>
+        inline bool
+        any(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename First1, typename Last, typename First2, typename F>
+        inline bool
+        any(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
+        {
+            return f(*first1, *first2) ||
+                detail::any(
+                    fusion::next(first1)
+                  , fusion::next(first2)
+                  , last
+                  , f
+                  , fusion::result_of::equal_to<
+                        typename fusion::result_of::next<First1>::type, Last>());
+        }
+    }
+
+    template <typename Sequence1, typename Sequence2, typename F>
+    inline bool
+    any(Sequence1 const& seq1, Sequence2& seq2, F f)
+    {
+        return detail::any(
+                fusion::begin(seq1)
+              , fusion::begin(seq2)
+              , fusion::end(seq1)
+              , f
+              , fusion::result_of::equal_to<
+                    typename fusion::result_of::begin<Sequence1>::type
+                  , typename fusion::result_of::end<Sequence1>::type>());
+    }
+
+    template <typename Sequence, typename F>
+    inline bool
+    any(Sequence const& seq, unused_type, F f)
+    {
+        return fusion::any(seq, f);
+    }
+
+}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/algorithm/any_if.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/algorithm/any_if.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,219 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ANY_IF_MAR_30_2007_1220PM)
+#define BOOST_SPIRIT_ANY_IF_MAR_30_2007_1220PM
+
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/fusion/include/next.hpp>
+#include <boost/fusion/include/deref.hpp>
+#include <boost/fusion/include/value_of.hpp>
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/any.hpp>
+#include <boost/fusion/include/make_cons.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/print.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This is a special version for a binary fusion::any. The predicate is
+    //  used to decide, whether to advance the second iterator or not.
+    //  This is needed for sequences containing components with unused
+    //  attributes.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Iterator, typename Pred>
+        struct apply_predicate
+        {
+            typedef typename
+                mpl::apply1<
+                    Pred,
+                    typename fusion::result_of::value_of<Iterator>::type
+                >::type
+            type;
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        //  if the predicate is true, attribute_next returns next(Iterator2),
+        //  otherwise Iterator2
+        namespace result_of
+        {
+            template <typename Iterator1, typename Iterator2, typename Pred>
+            struct attribute_next
+            {
+                typedef typename apply_predicate<Iterator1, Pred>::type pred;
+                typedef typename
+                    mpl::eval_if<
+                        pred,
+                        fusion::result_of::next<Iterator2>,
+                        mpl::identity<Iterator2>
+                    >::type
+                type;
+
+                template <typename Iterator>
+                static type
+                call(Iterator const& i, mpl::true_)
+                {
+                    return fusion::next(i);
+                }
+
+                template <typename Iterator>
+                static type
+                call(Iterator const& i, mpl::false_)
+                {
+                    return i;
+                }
+
+                template <typename Iterator>
+                static type
+                call(Iterator const& i)
+                {
+                    return call(i, pred());
+                }
+            };
+        }
+
+        template <typename Pred, typename Iterator1, typename Iterator2>
+        inline typename
+            result_of::attribute_next<Iterator1, Iterator2, Pred
+        >::type const
+        attribute_next(Iterator2 const& i)
+        {
+            return result_of::attribute_next<Iterator1, Iterator2, Pred>::call(i);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        //  if the predicate is true, attribute_value returns deref(Iterator2),
+        //  otherwise unused
+        namespace result_of
+        {
+            template <typename Iterator1, typename Iterator2, typename Pred>
+            struct attribute_value
+            {
+                typedef typename apply_predicate<Iterator1, Pred>::type pred;
+                typedef typename
+                    mpl::eval_if<
+                        pred,
+                        fusion::result_of::deref<Iterator2>,
+                        mpl::identity<unused_type const>
+                    >::type
+                type;
+
+                template <typename Iterator>
+                static type
+                call(Iterator const& i, mpl::true_)
+                {
+                    return fusion::deref(i);
+                }
+
+                template <typename Iterator>
+                static type
+                call(Iterator const&, mpl::false_)
+                {
+                    return unused;
+                }
+
+                template <typename Iterator>
+                static type
+                call(Iterator const& i)
+                {
+                    return call(i, pred());
+                }
+            };
+        }
+
+        template <typename Pred, typename Iterator1, typename Iterator2>
+        inline typename
+            result_of::attribute_value<Iterator1, Iterator2, Pred
+        >::type
+        attribute_value(Iterator2 const& i)
+        {
+            return result_of::attribute_value<Iterator1, Iterator2, Pred>::call(i);
+        }
+
+        ///////////////////////////////////////////////////////////////////////
+        template <
+            typename Pred, typename First1, typename Last, typename First2,
+            typename F
+        >
+        inline bool
+        any_if (First1 const&, First2 const&, Last const&, F const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <
+            typename Pred, typename First1, typename Last, typename First2,
+            typename F
+        >
+        inline bool
+        any_if (First1 const& first1, First2 const& first2, Last const& last,
+            F& f, mpl::false_)
+        {
+            return f(*first1, attribute_value<Pred, First1>(first2)) ||
+                detail::any_if<Pred>(
+                    fusion::next(first1)
+                  , attribute_next<Pred, First1>(first2)
+                  , last
+                  , f
+                  , fusion::result_of::equal_to<
+                        typename fusion::result_of::next<First1>::type, Last>());
+        }
+    }
+
+    template <typename Pred, typename Sequence1, typename Sequence2, typename F>
+    inline typename enable_if<fusion::traits::is_sequence<Sequence2>, bool>::type
+    any_if(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
+    {
+        return detail::any_if<Pred>(
+                fusion::begin(seq1)
+              , fusion::begin(seq2)
+              , fusion::end(seq1)
+              , f
+              , fusion::result_of::equal_to<
+                    typename fusion::result_of::begin<Sequence1>::type
+                  , typename fusion::result_of::end<Sequence1>::type>());
+    }
+
+    template <typename Pred, typename Sequence1, typename Attribute, typename F>
+    inline typename disable_if<fusion::traits::is_sequence<Attribute>, bool>::type
+    any_if(Sequence1 const& seq1, Attribute& attr, F f, Pred /*p*/)
+    {
+        typename
+            fusion::result_of::make_cons<Attribute&>::type
+        seq2(attr); // wrap attribute in a single element tuple
+
+        return detail::any_if<Pred>(
+                fusion::begin(seq1)
+              , fusion::begin(seq2)
+              , fusion::end(seq1)
+              , f
+              , fusion::result_of::equal_to<
+                    typename fusion::result_of::begin<Sequence1>::type
+                  , typename fusion::result_of::end<Sequence1>::type>());
+    }
+
+    template <typename Pred, typename Sequence, typename F>
+    inline bool
+    any_if(Sequence const& seq, unused_type const, F f, Pred)
+    {
+        return fusion::any(seq, f);
+    }
+
+}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/algorithm/any_ns.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/algorithm/any_ns.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,98 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ANY_NS_MARCH_13_2007_0827AM)
+#define BOOST_SPIRIT_ANY_NS_MARCH_13_2007_0827AM
+
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/include/equal_to.hpp>
+#include <boost/fusion/include/next.hpp>
+#include <boost/fusion/include/deref.hpp>
+#include <boost/fusion/include/begin.hpp>
+#include <boost/fusion/include/end.hpp>
+#include <boost/fusion/include/any.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit
+{
+    // A non-short circuiting (ns) version of the all algorithm (uses
+    // | instead of ||.
+
+    namespace detail
+    {
+        template <typename First1, typename Last, typename First2, typename F>
+        inline bool
+        any_ns(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename First1, typename Last, typename First2, typename F>
+        inline bool
+        any_ns(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
+        {
+            return (0 != (f(*first1, *first2) |
+                detail::any_ns(
+                    fusion::next(first1)
+                  , fusion::next(first2)
+                  , last
+                  , f
+                  , fusion::result_of::equal_to<
+                        typename fusion::result_of::next<First1>::type, Last>())));
+        }
+
+        template <typename First, typename Last, typename F>
+        inline bool
+        any_ns(First const&, Last const&, F const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename First, typename Last, typename F>
+        inline bool
+        any_ns(First const& first, Last const& last, F& f, mpl::false_)
+        {
+            return (0 != (f(*first) |
+                detail::any_ns(
+                    fusion::next(first)
+                  , last
+                  , f
+                  , fusion::result_of::equal_to<
+                        typename fusion::result_of::next<First>::type, Last>())));
+        }
+    }
+
+    template <typename Sequence1, typename Sequence2, typename F>
+    inline bool
+    any_ns(Sequence1 const& seq1, Sequence2& seq2, F f)
+    {
+        return detail::any_ns(
+                fusion::begin(seq1)
+              , fusion::begin(seq2)
+              , fusion::end(seq1)
+              , f
+              , fusion::result_of::equal_to<
+                    typename fusion::result_of::begin<Sequence1>::type
+                  , typename fusion::result_of::end<Sequence1>::type>());
+    }
+
+    template <typename Sequence, typename F>
+    inline bool
+    any_ns(Sequence const& seq, unused_type, F f)
+    {
+        return detail::any_ns(
+                fusion::begin(seq)
+              , fusion::end(seq)
+              , f
+              , fusion::result_of::equal_to<
+                    typename fusion::result_of::begin<Sequence>::type
+                  , typename fusion::result_of::end<Sequence>::type>());
+    }
+
+}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/argument.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/argument.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,204 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ARGUMENT_FEB_17_2007_0339PM)
+#define BOOST_SPIRIT_ARGUMENT_FEB_17_2007_0339PM
+
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/phoenix/core/argument.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/at.hpp>
+
+#if !defined(SPIRIT_ARG_LIMIT)
+# define SPIRIT_ARG_LIMIT PHOENIX_LIMIT
+#endif
+
+#define SPIRIT_DECLARE_ARG(z, n, data)                                          \
+    phoenix::actor<argument<n> > const                                          \
+        BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument<n>();                       \
+    phoenix::actor<attribute<n> > const                                         \
+        BOOST_PP_CAT(_r, n) = attribute<n>();
+
+namespace boost { namespace spirit
+{
+    namespace result_of
+    {
+        template <typename Sequence, int N>
+        struct get_arg
+        {
+            typedef typename
+                fusion::result_of::size<Sequence>::type
+            sequence_size;
+
+            // report invalid argument not found (N is out of bounds)
+            BOOST_MPL_ASSERT_MSG(
+                (N < sequence_size::value),
+                index_is_out_of_bounds, ());
+
+            typedef typename
+                fusion::result_of::at_c<Sequence, N>::type
+            type;
+
+            static type call(Sequence& seq)
+            {
+                return fusion::at_c<N>(seq);
+            }
+        };
+
+        template <typename Sequence, int N>
+        struct get_arg<Sequence&, N> : get_arg<Sequence, N>
+        {
+        };
+    }
+
+    template <int N, typename T>
+    typename result_of::get_arg<T, N>::type
+    get_arg(T& val)
+    {
+        return result_of::get_arg<T, N>::call(val);
+    }
+
+    struct attribute_context
+    {
+        typedef mpl::true_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            // FIXME: is this remove_const really necessary?
+            typedef typename
+                remove_const<
+                    typename mpl::at_c<typename Env::args_type, 0>::type
+                >::type
+            type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return fusion::at_c<0>(env.args());
+        }
+    };
+
+    template <int N>
+    struct argument
+    {
+        typedef mpl::true_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename
+                mpl::at_c<typename Env::args_type, 0>::type
+            arg_type;
+
+            typedef typename result_of::get_arg<arg_type, N>::type type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return get_arg<N>(fusion::at_c<0>(env.args()));
+        }
+    };
+
+    template <int N>
+    struct attribute
+    {
+        typedef mpl::true_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename
+                mpl::at_c<typename Env::args_type, 1>::type
+            arg_type;
+
+            typedef typename
+                result_of::get_arg<
+                    typename result_of::get_arg<arg_type, 0>::type
+                  , N
+                >::type
+            type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return get_arg<N>(get_arg<0>(fusion::at_c<1>(env.args())));
+        }
+    };
+
+    template <int N>
+    struct local_var
+    {
+        typedef mpl::true_ no_nullary;
+
+        template <typename Env>
+        struct result
+        {
+            typedef typename
+                mpl::at_c<typename Env::args_type, 1>::type
+            arg_type;
+
+            typedef typename
+                result_of::get_arg<
+                    typename result_of::get_arg<arg_type, 1>::type
+                  , N
+                >::type
+            type;
+        };
+
+        template <typename Env>
+        typename result<Env>::type
+        eval(Env const& env) const
+        {
+            return get_arg<N>(get_arg<1>(fusion::at_c<1>(env.args())));
+        }
+    };
+
+    namespace arg_names
+    {
+
+        phoenix::actor<attribute_context> const _0 = attribute_context();
+        
+        phoenix::actor<argument<0> > const _1 = argument<0>();
+        phoenix::actor<argument<1> > const _2 = argument<1>();
+        phoenix::actor<argument<2> > const _3 = argument<2>();
+
+        phoenix::actor<phoenix::argument<2> > const pass = phoenix::argument<2>();
+
+        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>();
+
+    //  Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
+        BOOST_PP_REPEAT_FROM_TO(
+            3, SPIRIT_ARG_LIMIT, SPIRIT_DECLARE_ARG, _)
+
+        phoenix::actor<local_var<0> > const _a = local_var<0>();
+        phoenix::actor<local_var<1> > const _b = local_var<1>();
+        phoenix::actor<local_var<2> > const _c = local_var<2>();
+        phoenix::actor<local_var<3> > const _d = local_var<3>();
+        phoenix::actor<local_var<4> > const _e = local_var<4>();
+        phoenix::actor<local_var<5> > const _f = local_var<5>();
+        phoenix::actor<local_var<6> > const _g = local_var<6>();
+        phoenix::actor<local_var<7> > const _h = local_var<7>();
+        phoenix::actor<local_var<8> > const _i = local_var<8>();
+        phoenix::actor<local_var<9> > const _j = local_var<9>();
+    }
+}}
+
+#undef SPIRIT_DECLARE_ARG
+#endif
Added: trunk/boost/spirit/home/support/as_variant.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/as_variant.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,93 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#if !defined(BOOST_SPIRIT_AS_VARIANT_NOV_16_2007_0420PM)
+#define BOOST_SPIRIT_AS_VARIANT_NOV_16_2007_0420PM
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/variant/variant_fwd.hpp>
+
+namespace boost { namespace spirit { namespace detail
+{
+    template <int size>
+    struct as_variant;
+
+    template <>
+    struct as_variant<0>
+    {
+        template <typename Iterator>
+        struct apply
+        {
+            typedef variant<> type;
+        };
+    };
+
+#define BOOST_FUSION_NEXT_ITERATOR(z, n, data)                                  \
+    typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type          \
+        BOOST_PP_CAT(I, BOOST_PP_INC(n));
+
+#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data)                             \
+    typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n))                              \
+        BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
+
+#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data)                              \
+    typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type      \
+        BOOST_PP_CAT(T, n);
+
+#define BOOST_PP_FILENAME_1 <boost/spirit/home/support/as_variant.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_VARIANT_LIMIT_TYPES)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_NEXT_ITERATOR
+#undef BOOST_FUSION_NEXT_CALL_ITERATOR
+#undef BOOST_FUSION_VALUE_OF_ITERATOR
+
+}}}
+
+namespace boost { namespace spirit
+{
+    template <typename Sequence>
+    struct as_variant
+    {
+        typedef typename
+            detail::as_variant<fusion::result_of::size<Sequence>::value>
+        gen;
+        typedef typename gen::
+            template apply<typename fusion::result_of::begin<Sequence>::type>::type
+        type;
+    };
+}}
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+    template <>
+    struct as_variant<N>
+    {
+        template <typename I0>
+        struct apply
+        {
+            BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
+            BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
+            typedef variant<BOOST_PP_ENUM_PARAMS(N, T)> type;
+        };
+    };
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
Added: trunk/boost/spirit/home/support/ascii.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/ascii.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ASCII_JAN_31_2006_0529PM)
+#define SPIRIT_ASCII_JAN_31_2006_0529PM
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit { namespace ascii
+{
+    typedef spirit::char_class::ascii char_set;
+    namespace tag = spirit::char_class::tag;
+
+    template <typename Class>
+    struct make_tag 
+      : proto::terminal<spirit::char_class::key<char_set, Class> > {};
+
+    typedef make_tag<tag::alnum>::type alnum_type;
+    typedef make_tag<tag::alpha>::type alpha_type;
+    typedef make_tag<tag::blank>::type blank_type;
+    typedef make_tag<tag::cntrl>::type cntrl_type;
+    typedef make_tag<tag::digit>::type digit_type;
+    typedef make_tag<tag::graph>::type graph_type;
+    typedef make_tag<tag::print>::type print_type;
+    typedef make_tag<tag::punct>::type punct_type;
+    typedef make_tag<tag::space>::type space_type;
+    typedef make_tag<tag::xdigit>::type xdigit_type;
+
+    alnum_type const alnum = {{}};
+    alpha_type const alpha = {{}};
+    blank_type const blank = {{}};
+    cntrl_type const cntrl = {{}};
+    digit_type const digit = {{}};
+    graph_type const graph = {{}};
+    print_type const print = {{}};
+    punct_type const punct = {{}};
+    space_type const space = {{}};
+    xdigit_type const xdigit = {{}};
+
+    typedef proto::terminal<
+        spirit::char_class::no_case_tag<char_set> >::type 
+    no_case_type;
+
+    no_case_type const no_case = no_case_type();
+
+    typedef proto::terminal<
+        spirit::char_class::lower_case_tag<char_set> >::type 
+    lower_type;
+    typedef proto::terminal<
+        spirit::char_class::upper_case_tag<char_set> >::type 
+    upper_type;
+
+    lower_type const lower = lower_type();
+    upper_type const upper = upper_type();
+
+#if defined(__GNUC__)
+    inline void silence_unused_warnings__ascii()
+    {
+        (void) alnum; (void) alpha; (void) blank; (void) cntrl; (void) digit; 
+        (void) graph; (void) print; (void) punct; (void) space; (void) xdigit;
+    }
+#endif
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/attribute_of.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/attribute_of.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,49 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_ATTRIBUTE_OF_JAN_29_2007_0954AM)
+#define BOOST_SPIRIT_ATTRIBUTE_OF_JAN_29_2007_0954AM
+
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace traits
+{
+    template <
+        typename Domain, typename T
+      , typename Context, typename Iterator = unused_type>
+    struct attribute_of :
+        attribute_of<
+            Domain
+          , typename result_of::as_component<Domain, T>::type
+          , Context
+          , Iterator
+        >
+    {
+    };
+
+    template <
+        typename Domain, typename Director, typename Elements
+      , typename Context, typename Iterator>
+    struct attribute_of<
+            Domain
+          , component<Domain, Director, Elements>
+          , Context
+          , Iterator
+        >
+    {
+        typedef
+            component<Domain, Director, Elements>
+        component_type;
+
+        typedef typename Director::template
+            attribute<component_type, Context, Iterator>::type
+        type;
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/attribute_transform.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/attribute_transform.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,167 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_ATTRIBUTE_TRANSFORM_DEC_17_2007_0718AM)
+#define BOOST_SPIRIT_ATTRIBUTE_TRANSFORM_DEC_17_2007_0718AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/variant/variant_fwd.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/fusion/include/filter_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit
+{
+    // Generalized attribute transformation utilities for Qi parsers
+
+    namespace traits
+    {
+        // Here, we provide policies for stripping single element fusion
+        // sequences. Add more specializations as needed.
+        template <typename T>
+        struct strip_single_element_sequence
+        {
+            typedef T type;
+        };
+
+        template <typename T>
+        struct strip_single_element_sequence<fusion::vector<T> >
+        {
+            //  Strips single element fusion vectors into its 'naked'
+            //  form: vector<T> --> T
+            typedef T type;
+        };
+
+        template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+        struct strip_single_element_sequence<
+            fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > >
+        {
+            //  Exception: Single element variants are not stripped!
+            typedef fusion::vector<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > type;
+        };
+    }
+
+    // Use this when building heterogeneous fusion sequences
+    // Note:
+    //
+    //      Director should have these nested metafunctions
+    //
+    //      1:  build_container<All, Filtered>
+    //
+    //          All: all child attributes
+    //          Filtered: all child attributes except unused
+    //
+    //      2:  transform_child<T>
+    //
+    //          T: child attribute
+    //
+    template <
+        typename Director, typename Component
+      , typename Iterator, typename Context>
+    struct build_fusion_sequence
+    {
+        template <
+            typename Domain, typename Director_
+          , typename Iterator_, typename Context_>
+        struct child_attribute
+        {
+            template <typename T>
+            struct result;
+
+            template <typename F, typename ChildComponent>
+            struct result<F(ChildComponent)>
+            {
+                typedef typename
+                    Director_::template transform_child<
+                        typename traits::attribute_of<
+                            Domain, ChildComponent, Context_, Iterator_>::type
+                    >::type
+                type;
+            };
+        };
+
+        // Compute the list of attributes of all sub-parsers
+        typedef
+            typename fusion::result_of::transform<
+                typename Component::elements_type
+              , child_attribute<
+                    typename Component::domain, Director, Iterator, Context>
+            >::type
+        all;
+
+        // Compute the list of all *used* attributes of sub-parsers
+        // (filter all unused parsers from the list)
+        typedef
+            typename fusion::result_of::filter_if<
+                all
+              , spirit::traits::is_not_unused<mpl::_>
+            >::type
+        filtered;
+
+        // Ask the director to build the actual fusion sequence.
+        // But *only if* the filtered sequence is not empty. i.e.
+        // if the sequence has all unused elements, our result
+        // will also be unused.
+        typedef
+            typename mpl::eval_if<
+                fusion::result_of::empty<filtered>
+              , mpl::identity<unused_type>
+              , typename Director::template build_container<all, filtered>
+            >::type
+        attribute_sequence;
+
+        // Finally, strip single element sequences into its
+        // naked form (e.g. vector<T> --> T)
+        typedef typename
+            traits::strip_single_element_sequence<attribute_sequence>::type
+        type;
+    };
+
+    // Use this when building homogeneous containers. Component
+    // is assumed to be a unary. Note:
+    //
+    //      Director should have this nested metafunction
+    //
+    //      1:  build_attribute_container<T>
+    //
+    //          T: the data-type for the container
+    //
+    template <
+        typename Director, typename Component
+      , typename Iterator, typename Context>
+    struct build_container
+    {
+        // Get the component's subject.
+        typedef typename
+            result_of::subject<Component>::type
+        subject_type;
+
+        // Get the subject's attribute
+        typedef typename
+            traits::attribute_of<
+                typename Component::domain, subject_type, Context, Iterator>::type
+        attr_type;
+
+        // If attribute is unused_type, return it as it is.
+        // If not, then ask the director to build the actual
+        // container for the attribute type.
+        typedef typename
+            mpl::if_<
+                is_same<unused_type, attr_type>
+              , unused_type
+              , typename Director::template
+                    build_attribute_container<attr_type>::type
+            >::type
+        type;
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/auxiliary/functor_holder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/auxiliary/functor_holder.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,33 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_FUNCTOR_HOLDER_APR_01_2007_0917AM)
+#define BOOST_SPIRIT_FUNCTOR_HOLDER_APR_01_2007_0917AM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Functor>
+    struct functor_holder
+    {
+        typedef Functor functor_type;
+        T held;
+    };
+
+    template <typename T, typename Functor>
+    struct make_functor_holder
+      : proto::terminal<functor_holder<T, Functor> >
+    {
+    };
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/auxiliary/meta_function_holder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/auxiliary/meta_function_holder.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,51 @@
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_SUPPORT_META_FUNCTION_HOLDER_SEP_03_2007_0302PM)
+#define BOOST_SPIRIT_SUPPORT_META_FUNCTION_HOLDER_SEP_03_2007_0302PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit 
+{
+    namespace detail
+    {
+        template <typename Functor, typename ParameterMF>
+        struct make_function_holder_base
+        {
+            typedef typename mpl::if_<
+                is_same<Functor, ParameterMF>, unused_type, ParameterMF
+            >::type type;
+        };
+    }
+
+    template <typename Functor, typename ParameterMF>
+    struct meta_function_holder 
+      : spirit::detail::make_function_holder_base<Functor, ParameterMF>::type
+    {
+    private:
+        typedef typename
+            spirit::detail::make_function_holder_base<Functor, ParameterMF>::type
+        base_type;
+
+    public:
+        meta_function_holder()
+        {}
+
+        meta_function_holder(ParameterMF const& mf)
+          : base_type(mf)
+        {}
+    };
+    
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/char_class.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/char_class.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,257 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_CHAR_CLASS_NOV_10_2006_0907AM)
+#define BOOST_SPIRIT_CHAR_CLASS_NOV_10_2006_0907AM
+
+#include <string>
+
+#include <boost/spirit/home/support/char_class/standard.hpp>
+#include <boost/spirit/home/support/char_class/standard_wide.hpp>
+#include <boost/spirit/home/support/char_class/ascii.hpp>
+#include <boost/spirit/home/support/char_class/iso8859_1.hpp>
+
+#include <boost/config.hpp>
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' warning
+#endif
+
+namespace boost { namespace spirit { namespace char_class
+{
+    namespace tag
+    {
+        // classification
+        struct alnum {};
+        struct alpha {};
+        struct digit {};
+        struct xdigit {};
+        struct cntrl {};
+        struct graph {};
+        struct lower {};
+        struct print {};
+        struct punct {};
+        struct space {};
+        struct blank {};
+        struct upper {};
+    }
+
+    // This composite tag type encodes both the character
+    // set and the specific char classification.
+    template <typename CharSet, typename CharClass>
+    struct key
+    {
+        typedef CharSet char_set;
+        typedef CharClass char_class;
+    };
+
+    // This identity tag types encode the character set.
+    struct no_case_base_tag {};
+    struct lower_case_base_tag {};
+    struct upper_case_base_tag {};
+
+    template <typename CharSet>
+    struct no_case_tag : no_case_base_tag
+    {
+        typedef CharSet char_set;
+    };
+
+    template <typename CharSet>
+    struct lower_case_tag : lower_case_base_tag
+    {
+        typedef CharSet char_set;
+        typedef tag::lower char_class;
+    };
+
+    template <typename CharSet>
+    struct upper_case_tag : upper_case_base_tag
+    {
+        typedef CharSet char_set;
+        typedef tag::upper char_class;
+    };
+
+    // Test characters for classification
+    template <typename CharSet>
+    struct classify
+    {
+        template <typename Char>
+        static bool
+        is(tag::alnum, Char ch)
+        {
+            return CharSet::isalnum(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::alpha, Char ch)
+        {
+            return CharSet::isalpha(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::digit, Char ch)
+        {
+            return CharSet::isdigit(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::xdigit, Char ch)
+        {
+            return CharSet::isxdigit(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::cntrl, Char ch)
+        {
+            return CharSet::iscntrl(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::graph, Char ch)
+        {
+            return CharSet::isgraph(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::lower, Char ch)
+        {
+            return CharSet::islower(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::print, Char ch)
+        {
+            return CharSet::isprint(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::punct, Char ch)
+        {
+            return CharSet::ispunct(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::space, Char ch)
+        {
+            return CharSet::isspace(ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::blank, Char ch)
+        {
+            return CharSet::isblank BOOST_PREVENT_MACRO_SUBSTITUTION (ch);
+        }
+
+        template <typename Char>
+        static bool
+        is(tag::upper, Char ch)
+        {
+            return CharSet::isupper(ch);
+        }
+    };
+
+    // Convert characters
+    template <typename CharSet>
+    struct convert
+    {
+        template <typename Char>
+        static Char
+        to(tag::lower, Char ch)
+        {
+            return CharSet::tolower(ch);
+        }
+
+        template <typename Char>
+        static Char
+        to(tag::upper, Char ch)
+        {
+            return CharSet::toupper(ch);
+        }
+    };
+
+    // Info on character classification
+    template <typename CharSet>
+    struct what
+    {
+        static char const* is(tag::alnum)
+        {
+            return "alnum";
+        }
+
+        static char const* is(tag::alpha)
+        {
+            return "alpha";
+        }
+
+        static char const* is(tag::digit)
+        {
+            return "digit";
+        }
+
+        static char const* is(tag::xdigit)
+        {
+            return "xdigit";
+        }
+
+        static char const* is(tag::cntrl)
+        {
+            return "cntrl";
+        }
+
+        static char const* is(tag::graph)
+        {
+            return "graph";
+        }
+
+        static char const* is(tag::lower)
+        {
+            return "lower";
+        }
+
+        static char const* is(tag::print)
+        {
+            return "print";
+        }
+
+        static char const* is(tag::punct)
+        {
+            return "punct";
+        }
+
+        static char const* is(tag::space)
+        {
+            return "space";
+        }
+
+        static char const* is(tag::blank)
+        {
+            return "blank";
+        }
+
+        static char const* is(tag::upper)
+        {
+            return "upper";
+        }
+    };
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
+
+
Added: trunk/boost/spirit/home/support/char_class/ascii.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/char_class/ascii.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,295 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_ASCII_APR_26_2006_1106PM)
+#define BOOST_SPIRIT_ASCII_APR_26_2006_1106PM
+
+#include <climits>
+#include <boost/assert.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// constants used to classify the single characters
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_CC_DIGIT    0x0001
+#define BOOST_CC_XDIGIT   0x0002
+#define BOOST_CC_ALPHA    0x0004
+#define BOOST_CC_CTRL     0x0008
+#define BOOST_CC_LOWER    0x0010
+#define BOOST_CC_UPPER    0x0020
+#define BOOST_CC_SPACE    0x0040
+#define BOOST_CC_PUNCT    0x0080
+
+namespace boost { namespace spirit { namespace char_class
+{ 
+    // The detection of isgraph(), isprint() and isblank() is done programmatically
+    // to keep the character type table small. Additionally, these functions are 
+    // rather seldom used and the programmatic detection is very simple.
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // ASCII character classification table
+    ///////////////////////////////////////////////////////////////////////////
+    const unsigned char ascii_char_types[] = 
+    {
+        /* NUL   0   0 */   BOOST_CC_CTRL,
+        /* SOH   1   1 */   BOOST_CC_CTRL,
+        /* STX   2   2 */   BOOST_CC_CTRL,
+        /* ETX   3   3 */   BOOST_CC_CTRL,
+        /* EOT   4   4 */   BOOST_CC_CTRL,
+        /* ENQ   5   5 */   BOOST_CC_CTRL,
+        /* ACK   6   6 */   BOOST_CC_CTRL,
+        /* BEL   7   7 */   BOOST_CC_CTRL,
+        /* BS    8   8 */   BOOST_CC_CTRL,
+        /* HT    9   9 */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* NL   10   a */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* VT   11   b */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* NP   12   c */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* CR   13   d */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* SO   14   e */   BOOST_CC_CTRL,
+        /* SI   15   f */   BOOST_CC_CTRL,
+        /* DLE  16  10 */   BOOST_CC_CTRL,
+        /* DC1  17  11 */   BOOST_CC_CTRL,
+        /* DC2  18  12 */   BOOST_CC_CTRL,
+        /* DC3  19  13 */   BOOST_CC_CTRL,
+        /* DC4  20  14 */   BOOST_CC_CTRL,
+        /* NAK  21  15 */   BOOST_CC_CTRL,
+        /* SYN  22  16 */   BOOST_CC_CTRL,
+        /* ETB  23  17 */   BOOST_CC_CTRL,
+        /* CAN  24  18 */   BOOST_CC_CTRL,
+        /* EM   25  19 */   BOOST_CC_CTRL,
+        /* SUB  26  1a */   BOOST_CC_CTRL,
+        /* ESC  27  1b */   BOOST_CC_CTRL,
+        /* FS   28  1c */   BOOST_CC_CTRL,
+        /* GS   29  1d */   BOOST_CC_CTRL,
+        /* RS   30  1e */   BOOST_CC_CTRL,
+        /* US   31  1f */   BOOST_CC_CTRL,
+        /* SP   32  20 */   BOOST_CC_SPACE,
+        /*  !   33  21 */   BOOST_CC_PUNCT,
+        /*  "   34  22 */   BOOST_CC_PUNCT,
+        /*  #   35  23 */   BOOST_CC_PUNCT,
+        /*  $   36  24 */   BOOST_CC_PUNCT,
+        /*  %   37  25 */   BOOST_CC_PUNCT,
+        /*  &   38  26 */   BOOST_CC_PUNCT,
+        /*  '   39  27 */   BOOST_CC_PUNCT,
+        /*  (   40  28 */   BOOST_CC_PUNCT,
+        /*  )   41  29 */   BOOST_CC_PUNCT,
+        /*  *   42  2a */   BOOST_CC_PUNCT,
+        /*  +   43  2b */   BOOST_CC_PUNCT,
+        /*  ,   44  2c */   BOOST_CC_PUNCT,
+        /*  -   45  2d */   BOOST_CC_PUNCT,
+        /*  .   46  2e */   BOOST_CC_PUNCT,
+        /*  /   47  2f */   BOOST_CC_PUNCT,
+        /*  0   48  30 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  1   49  31 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  2   50  32 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  3   51  33 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  4   52  34 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  5   53  35 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  6   54  36 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  7   55  37 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  8   56  38 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  9   57  39 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  :   58  3a */   BOOST_CC_PUNCT,
+        /*  ;   59  3b */   BOOST_CC_PUNCT,
+        /*  <   60  3c */   BOOST_CC_PUNCT,
+        /*  =   61  3d */   BOOST_CC_PUNCT,
+        /*  >   62  3e */   BOOST_CC_PUNCT,
+        /*  ?   63  3f */   BOOST_CC_PUNCT,
+        /*  @   64  40 */   BOOST_CC_PUNCT,
+        /*  A   65  41 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  B   66  42 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  C   67  43 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  D   68  44 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  E   69  45 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  F   70  46 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  G   71  47 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  H   72  48 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  I   73  49 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  J   74  4a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  K   75  4b */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  L   76  4c */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  M   77  4d */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  N   78  4e */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  O   79  4f */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  P   80  50 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Q   81  51 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  R   82  52 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  S   83  53 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  T   84  54 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  U   85  55 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  V   86  56 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  W   87  57 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  X   88  58 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Y   89  59 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Z   90  5a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  [   91  5b */   BOOST_CC_PUNCT,
+        /*  \   92  5c */   BOOST_CC_PUNCT,
+        /*  ]   93  5d */   BOOST_CC_PUNCT,
+        /*  ^   94  5e */   BOOST_CC_PUNCT,
+        /*  _   95  5f */   BOOST_CC_PUNCT,
+        /*  `   96  60 */   BOOST_CC_PUNCT,
+        /*  a   97  61 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  b   98  62 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  c   99  63 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  d  100  64 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  e  101  65 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  f  102  66 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  g  103  67 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  h  104  68 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  i  105  69 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  j  106  6a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  k  107  6b */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  l  108  6c */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  m  109  6d */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  n  110  6e */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  o  111  6f */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  p  112  70 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  q  113  71 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  r  114  72 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  s  115  73 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  t  116  74 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  u  117  75 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  v  118  76 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  w  119  77 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  x  120  78 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  y  121  79 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  z  122  7a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  {  123  7b */   BOOST_CC_PUNCT,
+        /*  |  124  7c */   BOOST_CC_PUNCT,
+        /*  }  125  7d */   BOOST_CC_PUNCT,
+        /*  ~  126  7e */   BOOST_CC_PUNCT,
+        /* DEL 127  7f */   BOOST_CC_CTRL,
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Test characters for specified conditions (using ASCII)
+    ///////////////////////////////////////////////////////////////////////////
+    struct ascii
+    {
+        typedef char char_type;
+
+        static bool
+        is_ascii(int ch)
+        {
+            return (0 == (ch & ~0x7f)) ? true : false;
+        }
+        
+        static int 
+        isalnum(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_ALPHA) 
+                || (ascii_char_types[ch] & BOOST_CC_DIGIT);
+        }
+        
+        static int 
+        isalpha(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_ALPHA);
+        }
+        
+        static int 
+        isdigit(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_DIGIT);
+        }
+        
+        static int 
+        isxdigit(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_XDIGIT);
+        }
+        
+        static int
+        iscntrl(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_CTRL);
+        }
+        
+        static int 
+        isgraph(int ch)
+        {
+            return ('\x21' <= ch && ch <= '\x7e');
+        }
+        
+        static int
+        islower(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_LOWER);
+        }
+        
+        static int
+        isprint(int ch)
+        {
+            return ('\x20' <= ch && ch <= '\x7e');
+        }
+        
+        static int
+        ispunct(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_PUNCT);
+        }
+        
+        static int
+        isspace(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_SPACE);
+        }
+        
+        static int
+        isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
+        {
+            return ('\x09' == ch || '\x20' == ch);
+        }
+        
+        static int
+        isupper(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return (ascii_char_types[ch] & BOOST_CC_UPPER);
+        }
+        
+        ///////////////////////////////////////////////////////////////////////
+        //  Simple character conversions
+        ///////////////////////////////////////////////////////////////////////
+    
+        static int
+        tolower(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return isupper(ch) ? (ch - 'A' + 'a') : ch;
+        }
+        
+        static int
+        toupper(int ch)
+        {
+            BOOST_ASSERT(is_ascii(ch));
+            return islower(ch) ? (ch - 'a' + 'A') : ch;
+        }
+    };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// undefine macros
+///////////////////////////////////////////////////////////////////////////////
+#undef BOOST_CC_DIGIT 
+#undef BOOST_CC_XDIGIT
+#undef BOOST_CC_ALPHA 
+#undef BOOST_CC_CTRL  
+#undef BOOST_CC_LOWER 
+#undef BOOST_CC_UPPER 
+#undef BOOST_CC_PUNCT 
+#undef BOOST_CC_SPACE 
+
+#endif
+
Added: trunk/boost/spirit/home/support/char_class/iso8859_1.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/char_class/iso8859_1.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,686 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_ISO8859_1_APR_26_2006_1106PM)
+#define BOOST_SPIRIT_ISO8859_1_APR_26_2006_1106PM
+
+#include <climits>
+#include <boost/assert.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// constants used to classify the single characters
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_CC_DIGIT    0x0001
+#define BOOST_CC_XDIGIT   0x0002
+#define BOOST_CC_ALPHA    0x0004
+#define BOOST_CC_CTRL     0x0008
+#define BOOST_CC_LOWER    0x0010
+#define BOOST_CC_UPPER    0x0020
+#define BOOST_CC_SPACE    0x0040
+#define BOOST_CC_PUNCT    0x0080
+
+namespace boost { namespace spirit { namespace char_class
+{
+    // The detection of isgraph(), isprint() and isblank() is done programmatically
+    // to keep the character type table small. Additionally, these functions are 
+    // rather seldom used and the programmatic detection is very simple.
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ISO 8859-1 character classification table
+    ///////////////////////////////////////////////////////////////////////////
+    const unsigned char iso8859_1_char_types[] = 
+    {
+        /* NUL   0   0 */   BOOST_CC_CTRL,
+        /* SOH   1   1 */   BOOST_CC_CTRL,
+        /* STX   2   2 */   BOOST_CC_CTRL,
+        /* ETX   3   3 */   BOOST_CC_CTRL,
+        /* EOT   4   4 */   BOOST_CC_CTRL,
+        /* ENQ   5   5 */   BOOST_CC_CTRL,
+        /* ACK   6   6 */   BOOST_CC_CTRL,
+        /* BEL   7   7 */   BOOST_CC_CTRL,
+        /* BS    8   8 */   BOOST_CC_CTRL,
+        /* HT    9   9 */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* NL   10   a */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* VT   11   b */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* NP   12   c */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* CR   13   d */   BOOST_CC_CTRL|BOOST_CC_SPACE,
+        /* SO   14   e */   BOOST_CC_CTRL,
+        /* SI   15   f */   BOOST_CC_CTRL,
+        /* DLE  16  10 */   BOOST_CC_CTRL,
+        /* DC1  17  11 */   BOOST_CC_CTRL,
+        /* DC2  18  12 */   BOOST_CC_CTRL,
+        /* DC3  19  13 */   BOOST_CC_CTRL,
+        /* DC4  20  14 */   BOOST_CC_CTRL,
+        /* NAK  21  15 */   BOOST_CC_CTRL,
+        /* SYN  22  16 */   BOOST_CC_CTRL,
+        /* ETB  23  17 */   BOOST_CC_CTRL,
+        /* CAN  24  18 */   BOOST_CC_CTRL,
+        /* EM   25  19 */   BOOST_CC_CTRL,
+        /* SUB  26  1a */   BOOST_CC_CTRL,
+        /* ESC  27  1b */   BOOST_CC_CTRL,
+        /* FS   28  1c */   BOOST_CC_CTRL,
+        /* GS   29  1d */   BOOST_CC_CTRL,
+        /* RS   30  1e */   BOOST_CC_CTRL,
+        /* US   31  1f */   BOOST_CC_CTRL,
+        /* SP   32  20 */   BOOST_CC_SPACE,
+        /*  !   33  21 */   BOOST_CC_PUNCT,
+        /*  "   34  22 */   BOOST_CC_PUNCT,
+        /*  #   35  23 */   BOOST_CC_PUNCT,
+        /*  $   36  24 */   BOOST_CC_PUNCT,
+        /*  %   37  25 */   BOOST_CC_PUNCT,
+        /*  &   38  26 */   BOOST_CC_PUNCT,
+        /*  '   39  27 */   BOOST_CC_PUNCT,
+        /*  (   40  28 */   BOOST_CC_PUNCT,
+        /*  )   41  29 */   BOOST_CC_PUNCT,
+        /*  *   42  2a */   BOOST_CC_PUNCT,
+        /*  +   43  2b */   BOOST_CC_PUNCT,
+        /*  ,   44  2c */   BOOST_CC_PUNCT,
+        /*  -   45  2d */   BOOST_CC_PUNCT,
+        /*  .   46  2e */   BOOST_CC_PUNCT,
+        /*  /   47  2f */   BOOST_CC_PUNCT,
+        /*  0   48  30 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  1   49  31 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  2   50  32 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  3   51  33 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  4   52  34 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  5   53  35 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  6   54  36 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  7   55  37 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  8   56  38 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  9   57  39 */   BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
+        /*  :   58  3a */   BOOST_CC_PUNCT,
+        /*  ;   59  3b */   BOOST_CC_PUNCT,
+        /*  <   60  3c */   BOOST_CC_PUNCT,
+        /*  =   61  3d */   BOOST_CC_PUNCT,
+        /*  >   62  3e */   BOOST_CC_PUNCT,
+        /*  ?   63  3f */   BOOST_CC_PUNCT,
+        /*  @   64  40 */   BOOST_CC_PUNCT,
+        /*  A   65  41 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  B   66  42 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  C   67  43 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  D   68  44 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  E   69  45 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  F   70  46 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
+        /*  G   71  47 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  H   72  48 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  I   73  49 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  J   74  4a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  K   75  4b */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  L   76  4c */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  M   77  4d */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  N   78  4e */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  O   79  4f */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  P   80  50 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Q   81  51 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  R   82  52 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  S   83  53 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  T   84  54 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  U   85  55 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  V   86  56 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  W   87  57 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  X   88  58 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Y   89  59 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Z   90  5a */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  [   91  5b */   BOOST_CC_PUNCT,
+        /*  \   92  5c */   BOOST_CC_PUNCT,
+        /*  ]   93  5d */   BOOST_CC_PUNCT,
+        /*  ^   94  5e */   BOOST_CC_PUNCT,
+        /*  _   95  5f */   BOOST_CC_PUNCT,
+        /*  `   96  60 */   BOOST_CC_PUNCT,
+        /*  a   97  61 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  b   98  62 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  c   99  63 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  d  100  64 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  e  101  65 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  f  102  66 */   BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
+        /*  g  103  67 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  h  104  68 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  i  105  69 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  j  106  6a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  k  107  6b */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  l  108  6c */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  m  109  6d */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  n  110  6e */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  o  111  6f */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  p  112  70 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  q  113  71 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  r  114  72 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  s  115  73 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  t  116  74 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  u  117  75 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  v  118  76 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  w  119  77 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  x  120  78 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  y  121  79 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  z  122  7a */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  {  123  7b */   BOOST_CC_PUNCT,
+        /*  |  124  7c */   BOOST_CC_PUNCT,
+        /*  }  125  7d */   BOOST_CC_PUNCT,
+        /*  ~  126  7e */   BOOST_CC_PUNCT,
+        /* DEL 127  7f */   BOOST_CC_CTRL,
+        /* --  128  80 */   BOOST_CC_CTRL,
+        /* --  129  81 */   BOOST_CC_CTRL,
+        /* --  130  82 */   BOOST_CC_CTRL,
+        /* --  131  83 */   BOOST_CC_CTRL,
+        /* --  132  84 */   BOOST_CC_CTRL,
+        /* --  133  85 */   BOOST_CC_CTRL,
+        /* --  134  86 */   BOOST_CC_CTRL,
+        /* --  135  87 */   BOOST_CC_CTRL,
+        /* --  136  88 */   BOOST_CC_CTRL,
+        /* --  137  89 */   BOOST_CC_CTRL,
+        /* --  138  8a */   BOOST_CC_CTRL,
+        /* --  139  8b */   BOOST_CC_CTRL,
+        /* --  140  8c */   BOOST_CC_CTRL,
+        /* --  141  8d */   BOOST_CC_CTRL,
+        /* --  142  8e */   BOOST_CC_CTRL,
+        /* --  143  8f */   BOOST_CC_CTRL,
+        /* --  144  90 */   BOOST_CC_CTRL,
+        /* --  145  91 */   BOOST_CC_CTRL,
+        /* --  146  92 */   BOOST_CC_CTRL,
+        /* --  147  93 */   BOOST_CC_CTRL,
+        /* --  148  94 */   BOOST_CC_CTRL,
+        /* --  149  95 */   BOOST_CC_CTRL,
+        /* --  150  96 */   BOOST_CC_CTRL,
+        /* --  151  97 */   BOOST_CC_CTRL,
+        /* --  152  98 */   BOOST_CC_CTRL,
+        /* --  153  99 */   BOOST_CC_CTRL,
+        /* --  154  9a */   BOOST_CC_CTRL,
+        /* --  155  9b */   BOOST_CC_CTRL,
+        /* --  156  9c */   BOOST_CC_CTRL,
+        /* --  157  9d */   BOOST_CC_CTRL,
+        /* --  158  9e */   BOOST_CC_CTRL,
+        /* --  159  9f */   BOOST_CC_CTRL,
+        /*     160  a0 */   BOOST_CC_SPACE,
+        /*  ¡  161  a1 */   BOOST_CC_PUNCT,
+        /*  ¢  162  a2 */   BOOST_CC_PUNCT,
+        /*  £  163  a3 */   BOOST_CC_PUNCT,
+        /*  ¤  164  a4 */   BOOST_CC_PUNCT,
+        /*  ¥  165  a5 */   BOOST_CC_PUNCT,
+        /*  ¦  166  a6 */   BOOST_CC_PUNCT,
+        /*  §  167  a7 */   BOOST_CC_PUNCT,
+        /*  ¨  168  a8 */   BOOST_CC_PUNCT,
+        /*  ©  169  a9 */   BOOST_CC_PUNCT,
+        /*  ª  170  aa */   BOOST_CC_PUNCT,
+        /*  «  171  ab */   BOOST_CC_PUNCT,
+        /*  ¬  172  ac */   BOOST_CC_PUNCT,
+        /*    173  ad */   BOOST_CC_PUNCT,
+        /*  ®  174  ae */   BOOST_CC_PUNCT,
+        /*  ¯  175  af */   BOOST_CC_PUNCT,
+        /*  °  176  b0 */   BOOST_CC_PUNCT,
+        /*  ±  177  b1 */   BOOST_CC_PUNCT,
+        /*  ²  178  b2 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,
+        /*  ³  179  b3 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,
+        /*  ´  180  b4 */   BOOST_CC_PUNCT,
+        /*  µ  181  b5 */   BOOST_CC_PUNCT,
+        /*  ¶  182  b6 */   BOOST_CC_PUNCT,
+        /*  ·  183  b7 */   BOOST_CC_PUNCT,
+        /*  ¸  184  b8 */   BOOST_CC_PUNCT,
+        /*  ¹  185  b9 */   BOOST_CC_DIGIT|BOOST_CC_PUNCT,
+        /*  º  186  ba */   BOOST_CC_PUNCT,
+        /*  »  187  bb */   BOOST_CC_PUNCT,
+        /*  ¼  188  bc */   BOOST_CC_PUNCT,
+        /*  ½  189  bd */   BOOST_CC_PUNCT,
+        /*  ¾  190  be */   BOOST_CC_PUNCT,
+        /*  ¿  191  bf */   BOOST_CC_PUNCT,
+        /*  À  192  c0 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Á  193  c1 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Â  194  c2 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ã  195  c3 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ä  196  c4 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Å  197  c5 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Æ  198  c6 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ç  199  c7 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  È  200  c8 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  É  201  c9 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ê  202  ca */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ë  203  cb */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ì  204  cc */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Í  205  cd */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Î  206  ce */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ï  207  cf */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ð  208  d0 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ñ  209  d1 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ò  210  d2 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ó  211  d3 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ô  212  d4 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Õ  213  d5 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ö  214  d6 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  ×  215  d7 */   BOOST_CC_PUNCT,
+        /*  Ø  216  d8 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ù  217  d9 */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ú  218  da */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Û  219  db */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ü  220  dc */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Ý  221  dd */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  Þ  222  de */   BOOST_CC_ALPHA|BOOST_CC_UPPER,
+        /*  ß  223  df */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  à  224  e0 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  á  225  e1 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  â  226  e2 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ã  227  e3 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ä  228  e4 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  å  229  e5 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  æ  230  e6 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ç  231  e7 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  è  232  e8 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  é  233  e9 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ê  234  ea */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ë  235  eb */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ì  236  ec */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  í  237  ed */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  î  238  ee */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ï  239  ef */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ð  240  f0 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ñ  241  f1 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ò  242  f2 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ó  243  f3 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ô  244  f4 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  õ  245  f5 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ö  246  f6 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ÷  247  f7 */   BOOST_CC_PUNCT,
+        /*  ø  248  f8 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ù  249  f9 */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ú  250  fa */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  û  251  fb */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ü  252  fc */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ý  253  fd */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  þ  254  fe */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+        /*  ÿ  255  ff */   BOOST_CC_ALPHA|BOOST_CC_LOWER,
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ISO 8859-1 character conversion table
+    ///////////////////////////////////////////////////////////////////////////
+    const unsigned char iso8859_1_char_conversion[] = 
+    {
+        /* NUL   0   0 */   '\0',
+        /* SOH   1   1 */   '\0',
+        /* STX   2   2 */   '\0',
+        /* ETX   3   3 */   '\0',
+        /* EOT   4   4 */   '\0',
+        /* ENQ   5   5 */   '\0',
+        /* ACK   6   6 */   '\0',
+        /* BEL   7   7 */   '\0',
+        /* BS    8   8 */   '\0',
+        /* HT    9   9 */   '\0',
+        /* NL   10   a */   '\0',
+        /* VT   11   b */   '\0',
+        /* NP   12   c */   '\0',
+        /* CR   13   d */   '\0',
+        /* SO   14   e */   '\0',
+        /* SI   15   f */   '\0',
+        /* DLE  16  10 */   '\0',
+        /* DC1  17  11 */   '\0',
+        /* DC2  18  12 */   '\0',
+        /* DC3  19  13 */   '\0',
+        /* DC4  20  14 */   '\0',
+        /* NAK  21  15 */   '\0',
+        /* SYN  22  16 */   '\0',
+        /* ETB  23  17 */   '\0',
+        /* CAN  24  18 */   '\0',
+        /* EM   25  19 */   '\0',
+        /* SUB  26  1a */   '\0',
+        /* ESC  27  1b */   '\0',
+        /* FS   28  1c */   '\0',
+        /* GS   29  1d */   '\0',
+        /* RS   30  1e */   '\0',
+        /* US   31  1f */   '\0',
+        /* SP   32  20 */   '\0',
+        /*  !   33  21 */   '\0',
+        /*  "   34  22 */   '\0',
+        /*  #   35  23 */   '\0',
+        /*  $   36  24 */   '\0',
+        /*  %   37  25 */   '\0',
+        /*  &   38  26 */   '\0',
+        /*  '   39  27 */   '\0',
+        /*  (   40  28 */   '\0',
+        /*  )   41  29 */   '\0',
+        /*  *   42  2a */   '\0',
+        /*  +   43  2b */   '\0',
+        /*  ,   44  2c */   '\0',
+        /*  -   45  2d */   '\0',
+        /*  .   46  2e */   '\0',
+        /*  /   47  2f */   '\0',
+        /*  0   48  30 */   '\0',
+        /*  1   49  31 */   '\0',
+        /*  2   50  32 */   '\0',
+        /*  3   51  33 */   '\0',
+        /*  4   52  34 */   '\0',
+        /*  5   53  35 */   '\0',
+        /*  6   54  36 */   '\0',
+        /*  7   55  37 */   '\0',
+        /*  8   56  38 */   '\0',
+        /*  9   57  39 */   '\0',
+        /*  :   58  3a */   '\0',
+        /*  ;   59  3b */   '\0',
+        /*  <   60  3c */   '\0',
+        /*  =   61  3d */   '\0',
+        /*  >   62  3e */   '\0',
+        /*  ?   63  3f */   '\0',
+        /*  @   64  40 */   '\0',
+        /*  A   65  41 */   'a',
+        /*  B   66  42 */   'b',
+        /*  C   67  43 */   'c',
+        /*  D   68  44 */   'd',
+        /*  E   69  45 */   'e',
+        /*  F   70  46 */   'f',
+        /*  G   71  47 */   'g',
+        /*  H   72  48 */   'h',
+        /*  I   73  49 */   'i',
+        /*  J   74  4a */   'j',
+        /*  K   75  4b */   'k',
+        /*  L   76  4c */   'l',
+        /*  M   77  4d */   'm',
+        /*  N   78  4e */   'n',
+        /*  O   79  4f */   'o',
+        /*  P   80  50 */   'p',
+        /*  Q   81  51 */   'q',
+        /*  R   82  52 */   'r',
+        /*  S   83  53 */   's',
+        /*  T   84  54 */   't',
+        /*  U   85  55 */   'u',
+        /*  V   86  56 */   'v',
+        /*  W   87  57 */   'w',
+        /*  X   88  58 */   'x',
+        /*  Y   89  59 */   'y',
+        /*  Z   90  5a */   'z',
+        /*  [   91  5b */   '\0',
+        /*  \   92  5c */   '\0',
+        /*  ]   93  5d */   '\0',
+        /*  ^   94  5e */   '\0',
+        /*  _   95  5f */   '\0',
+        /*  `   96  60 */   '\0',
+        /*  a   97  61 */   'A',
+        /*  b   98  62 */   'B',
+        /*  c   99  63 */   'C',
+        /*  d  100  64 */   'D',
+        /*  e  101  65 */   'E',
+        /*  f  102  66 */   'F',
+        /*  g  103  67 */   'G',
+        /*  h  104  68 */   'H',
+        /*  i  105  69 */   'I',
+        /*  j  106  6a */   'J',
+        /*  k  107  6b */   'K',
+        /*  l  108  6c */   'L',
+        /*  m  109  6d */   'M',
+        /*  n  110  6e */   'N',
+        /*  o  111  6f */   'O',
+        /*  p  112  70 */   'P',
+        /*  q  113  71 */   'Q',
+        /*  r  114  72 */   'R',
+        /*  s  115  73 */   'S',
+        /*  t  116  74 */   'T',
+        /*  u  117  75 */   'U',
+        /*  v  118  76 */   'V',
+        /*  w  119  77 */   'W',
+        /*  x  120  78 */   'X',
+        /*  y  121  79 */   'Y',
+        /*  z  122  7a */   'Z',
+        /*  {  123  7b */   '\0',
+        /*  |  124  7c */   '\0',
+        /*  }  125  7d */   '\0',
+        /*  ~  126  7e */   '\0',
+        /* DEL 127  7f */   '\0',
+        /* --  128  80 */   '\0',
+        /* --  129  81 */   '\0',
+        /* --  130  82 */   '\0',
+        /* --  131  83 */   '\0',
+        /* --  132  84 */   '\0',
+        /* --  133  85 */   '\0',
+        /* --  134  86 */   '\0',
+        /* --  135  87 */   '\0',
+        /* --  136  88 */   '\0',
+        /* --  137  89 */   '\0',
+        /* --  138  8a */   '\0',
+        /* --  139  8b */   '\0',
+        /* --  140  8c */   '\0',
+        /* --  141  8d */   '\0',
+        /* --  142  8e */   '\0',
+        /* --  143  8f */   '\0',
+        /* --  144  90 */   '\0',
+        /* --  145  91 */   '\0',
+        /* --  146  92 */   '\0',
+        /* --  147  93 */   '\0',
+        /* --  148  94 */   '\0',
+        /* --  149  95 */   '\0',
+        /* --  150  96 */   '\0',
+        /* --  151  97 */   '\0',
+        /* --  152  98 */   '\0',
+        /* --  153  99 */   '\0',
+        /* --  154  9a */   '\0',
+        /* --  155  9b */   '\0',
+        /* --  156  9c */   '\0',
+        /* --  157  9d */   '\0',
+        /* --  158  9e */   '\0',
+        /* --  159  9f */   '\0',
+        /*     160  a0 */   '\0',
+        /*  ¡  161  a1 */   '\0',
+        /*  ¢  162  a2 */   '\0',
+        /*  £  163  a3 */   '\0',
+        /*  ¤  164  a4 */   '\0',
+        /*  ¥  165  a5 */   '\0',
+        /*  ¦  166  a6 */   '\0',
+        /*  §  167  a7 */   '\0',
+        /*  ¨  168  a8 */   '\0',
+        /*  ©  169  a9 */   '\0',
+        /*  ª  170  aa */   '\0',
+        /*  «  171  ab */   '\0',
+        /*  ¬  172  ac */   '\0',
+        /*    173  ad */   '\0',
+        /*  ®  174  ae */   '\0',
+        /*  ¯  175  af */   '\0',
+        /*  °  176  b0 */   '\0',
+        /*  ±  177  b1 */   '\0',
+        /*  ²  178  b2 */   '\0',
+        /*  ³  179  b3 */   '\0',
+        /*  ´  180  b4 */   '\0',
+        /*  µ  181  b5 */   '\0',
+        /*  ¶  182  b6 */   '\0',
+        /*  ·  183  b7 */   '\0',
+        /*  ¸  184  b8 */   '\0',
+        /*  ¹  185  b9 */   '\0',
+        /*  º  186  ba */   '\0',
+        /*  »  187  bb */   '\0',
+        /*  ¼  188  bc */   '\0',
+        /*  ½  189  bd */   '\0',
+        /*  ¾  190  be */   '\0',
+        /*  ¿  191  bf */   '\0',
+        /*  à  192  c0 */   0xc0,
+        /*  á  193  c1 */   0xc1,
+        /*  â  194  c2 */   0xc2,
+        /*  ã  195  c3 */   0xc3,
+        /*  ä  196  c4 */   0xc4,
+        /*  å  197  c5 */   0xc5,
+        /*  æ  198  c6 */   0xc6,
+        /*  ç  199  c7 */   0xc7,
+        /*  è  200  c8 */   0xc8,
+        /*  é  201  c9 */   0xc9,
+        /*  ê  202  ca */   0xca,
+        /*  ë  203  cb */   0xcb,
+        /*  ì  204  cc */   0xcc,
+        /*  í  205  cd */   0xcd,
+        /*  î  206  ce */   0xce,
+        /*  ï  207  cf */   0xcf,
+        /*  ð  208  d0 */   0xd0,
+        /*  ñ  209  d1 */   0xd1,
+        /*  ò  210  d2 */   0xd2,
+        /*  ó  211  d3 */   0xd3,
+        /*  ô  212  d4 */   0xd4,
+        /*  õ  213  d5 */   0xd5,
+        /*  ö  214  d6 */   0xd6,
+        /*  ×  215  d7 */   '\0',
+        /*  ø  216  d8 */   0xd8,
+        /*  ù  217  d9 */   0xd9,
+        /*  ú  218  da */   0xda,
+        /*  û  219  db */   0xdb,
+        /*  ü  220  dc */   0xdc,
+        /*  ý  221  dd */   0xdd,
+        /*  þ  222  de */   0xde,
+        /*  ß  223  df */   '\0',
+        /*  À  224  e0 */   0xe0,
+        /*  Á  225  e1 */   0xe1,
+        /*  Â  226  e2 */   0xe2,
+        /*  Ã  227  e3 */   0xe3,
+        /*  Ä  228  e4 */   0xe4,
+        /*  Å  229  e5 */   0xe5,
+        /*  Æ  230  e6 */   0xe6,
+        /*  Ç  231  e7 */   0xe7,
+        /*  È  232  e8 */   0xe8,
+        /*  É  233  e9 */   0xe9,
+        /*  Ê  234  ea */   0xea,
+        /*  Ë  235  eb */   0xeb,
+        /*  Ì  236  ec */   0xec,
+        /*  Í  237  ed */   0xed,
+        /*  Î  238  ee */   0xee,
+        /*  Ï  239  ef */   0xef,
+        /*  Ð  240  f0 */   0xf0,
+        /*  Ñ  241  f1 */   0xf1,
+        /*  Ò  242  f2 */   0xf2,
+        /*  Ó  243  f3 */   0xf3,
+        /*  Ô  244  f4 */   0xf4,
+        /*  Õ  245  f5 */   0xf5,
+        /*  Ö  246  f6 */   0xf6,
+        /*  ÷  247  f7 */   '\0',
+        /*  Ø  248  f8 */   0xf8,
+        /*  Ù  249  f9 */   0xf9,
+        /*  Ú  250  fa */   0xfa,
+        /*  Û  251  fb */   0xfb,
+        /*  Ü  252  fc */   0xfc,
+        /*  Ý  253  fd */   0xfd,
+        /*  Þ  254  fe */   0xfe,
+        /*  ÿ  255  ff */   '\0',
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Test characters for specified conditions (using iso8859-1)
+    ///////////////////////////////////////////////////////////////////////////
+    struct iso8859_1
+    {
+        typedef char char_type;
+
+        static bool
+        is_ascii(int ch)
+        {
+            return (0 == (ch & ~0x7f)) ? true : false;
+        }
+    
+        static int 
+        isalnum(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA) 
+                || (iso8859_1_char_types[ch] & BOOST_CC_DIGIT);
+        }
+        
+        static int 
+        isalpha(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA);
+        }
+        
+        static int 
+        isdigit(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_DIGIT);
+        }
+        
+        static int 
+        isxdigit(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_XDIGIT);
+        }
+        
+        static int
+        iscntrl(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_CTRL);
+        }
+        
+        static int 
+        isgraph(int ch)
+        {
+            return ('\x21' <= ch && ch <= '\x7e') || ('\xa1' <= ch && ch <= '\xff');
+        }
+        
+        static int
+        islower(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_LOWER);
+        }
+        
+        static int
+        isprint(int ch)
+        {
+            return ('\x20' <= ch && ch <= '\x7e') || ('\xa0' <= ch && ch <= '\xff');
+        }
+        
+        static int
+        ispunct(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_PUNCT);
+        }
+        
+        static int
+        isspace(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_SPACE);
+        }
+        
+        static int
+        isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
+        {
+            return ('\x09' == ch || '\x20' == ch || '\xa0' == ch);
+        }
+        
+        static int
+        isupper(int ch)
+        {
+            BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
+            return (iso8859_1_char_types[ch] & BOOST_CC_UPPER);
+        }
+        
+    ///////////////////////////////////////////////////////////////////////////
+    //  Simple character conversions
+    ///////////////////////////////////////////////////////////////////////////
+    
+        static int
+        tolower(int ch)
+        {
+            return isupper(ch) && '\0' != iso8859_1_char_conversion[ch] ? 
+                iso8859_1_char_conversion[ch] : ch;
+        }
+        
+        static int
+        toupper(int ch)
+        {
+            return islower(ch) && '\0' != iso8859_1_char_conversion[ch] ? 
+                iso8859_1_char_conversion[ch] : ch;
+        }
+    };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// undefine macros
+///////////////////////////////////////////////////////////////////////////////
+#undef BOOST_CC_DIGIT 
+#undef BOOST_CC_XDIGIT
+#undef BOOST_CC_ALPHA 
+#undef BOOST_CC_CTRL  
+#undef BOOST_CC_LOWER 
+#undef BOOST_CC_UPPER 
+#undef BOOST_CC_PUNCT 
+#undef BOOST_CC_SPACE 
+
+#endif
+
Added: trunk/boost/spirit/home/support/char_class/standard.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/char_class/standard.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,117 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_STANDARD_APR_26_2006_1106PM)
+#define BOOST_SPIRIT_STANDARD_APR_26_2006_1106PM
+
+#include <cctype>
+
+namespace boost { namespace spirit { namespace char_class
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Test characters for specified conditions (using std functions)
+    ///////////////////////////////////////////////////////////////////////////
+    struct standard
+    {
+        typedef char char_type;
+
+        static bool
+        is_ascii(int ch)
+        {
+            return (0 == (ch & ~0x7f)) ? true : false;
+        }
+    
+        static int 
+        isalnum(int ch)
+        {
+            return std::isalnum(ch);
+        }
+        
+        static int 
+        isalpha(int ch)
+        {
+            return std::isalpha(ch);
+        }
+        
+        static int 
+        isdigit(int ch)
+        {
+            return std::isdigit(ch);
+        }
+        
+        static int 
+        isxdigit(int ch)
+        {
+            return std::isxdigit(ch);
+        }
+        
+        static int
+        iscntrl(int ch)
+        {
+            return std::iscntrl(ch);
+        }
+        
+        static int 
+        isgraph(int ch)
+        {
+            return std::isgraph(ch);
+        }
+        
+        static int
+        islower(int ch)
+        {
+            return std::islower(ch);
+        }
+        
+        static int
+        isprint(int ch)
+        {
+            return std::isprint(ch);
+        }
+        
+        static int
+        ispunct(int ch)
+        {
+            return std::ispunct(ch);
+        }
+        
+        static int
+        isspace(int ch)
+        {
+            return std::isspace(ch);
+        }
+        
+        static int
+        isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
+        {
+            return (ch == ' ' || ch == '\t'); 
+        }
+        
+        static int
+        isupper(int ch)
+        {
+            return std::isupper(ch);
+        }
+    
+    ///////////////////////////////////////////////////////////////////////////////
+    //  Simple character conversions
+    ///////////////////////////////////////////////////////////////////////////////
+        static int
+        tolower(int ch)
+        {
+            return std::tolower(ch);
+        }
+        
+        static int
+        toupper(int ch)
+        {
+            return std::toupper(ch);
+        }
+    };
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/char_class/standard_wide.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/char_class/standard_wide.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,137 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_STANDARD_WIDE_NOV_10_2006_0913AM)
+#define BOOST_SPIRIT_STANDARD_WIDE_NOV_10_2006_0913AM
+
+#include <cwctype>
+
+namespace boost { namespace spirit { namespace char_class
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Test characters for specified conditions (using std wchar_t functions)
+    ///////////////////////////////////////////////////////////////////////////
+    struct standard_wide
+    {
+        typedef wchar_t char_type;
+
+        template <typename Char>
+        static typename std::char_traits<Char>::int_type
+        to_int_type(Char ch)
+        {
+            return std::char_traits<Char>::to_int_type(ch);
+        }
+    
+        template <typename Char>
+        static Char
+        to_char_type(typename std::char_traits<Char>::int_type ch)
+        {
+            return std::char_traits<Char>::to_char_type(ch);
+        }
+        
+        static bool 
+        isalnum(wchar_t ch)
+        { 
+            using namespace std;
+            return iswalnum(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isalpha(wchar_t ch)
+        { 
+            using namespace std;
+            return iswalpha(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        iscntrl(wchar_t ch)
+        { 
+            using namespace std;
+            return iswcntrl(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isdigit(wchar_t ch)
+        { 
+            using namespace std;
+            return iswdigit(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isgraph(wchar_t ch)
+        { 
+            using namespace std;
+            return iswgraph(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        islower(wchar_t ch)
+        { 
+            using namespace std;
+            return iswlower(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isprint(wchar_t ch)
+        { 
+            using namespace std;
+            return iswprint(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        ispunct(wchar_t ch)
+        { 
+            using namespace std;
+            return iswpunct(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isspace(wchar_t ch)
+        { 
+            using namespace std;
+            return iswspace(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isupper(wchar_t ch)
+        { 
+            using namespace std;
+            return iswupper(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isxdigit(wchar_t ch)
+        { 
+            using namespace std;
+            return iswxdigit(to_int_type(ch)) ? true : false; 
+        }
+    
+        static bool 
+        isblank BOOST_PREVENT_MACRO_SUBSTITUTION (wchar_t ch)
+        { 
+            return (ch == L' ' || ch == L'\t'); 
+        } 
+    
+        static wchar_t 
+        tolower(wchar_t ch)
+        { 
+            using namespace std;
+            return isupper(ch) ?
+                to_char_type<wchar_t>(towlower(to_int_type(ch))) : ch; 
+        }
+    
+        static wchar_t 
+        toupper(wchar_t ch)
+        { 
+            using namespace std;
+            return islower(ch) ?
+                to_char_type<wchar_t>(towupper(to_int_type(ch))) : ch; 
+        }
+    };
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/component.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/component.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,287 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_COMPONENT_JAN_14_2007_1102AM)
+#define BOOST_SPIRIT_COMPONENT_JAN_14_2007_1102AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/apply.hpp>
+
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  component generalizes a spirit component. A component can be a parser,
+    //  a primitive-parser, a composite-parser, a generator, etc.
+    //  A component has:
+    //
+    //      1) Domain: The world it operates on (purely a type e.g. qi::domain).
+    //      2) Director: Its Director (purely a type e.g. qi::sequence)
+    //      3) Elements: For composites, a tuple of components
+    //                   For primitives, a tuple of arbitrary information
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Director, typename Elements>
+    struct component
+    {
+        typedef Domain domain;
+        typedef Director director;
+        typedef Elements elements_type;
+
+        component()
+        {
+        }
+
+        component(Elements const& elements)
+          : elements(elements)
+        {
+        }
+
+        template <typename Elements2>
+        component(component<Domain, Director, Elements2> const& other)
+          : elements(other.elements)
+        {
+            // allow copy from components with compatible elements
+        }
+
+        elements_type elements;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Utils for extracting child components
+    ///////////////////////////////////////////////////////////////////////////
+    namespace result_of
+    {
+        template <typename Component>
+        struct subject
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 0>::type
+            type;
+        };
+
+        template <typename Component>
+        struct left
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 0>::type
+            type;
+        };
+
+        template <typename Component>
+        struct right
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 1>::type
+            type;
+        };
+
+        template <typename Component>
+        struct argument1
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 1>::type
+            type;
+        };
+
+        template <typename Component>
+        struct argument2
+        {
+            typedef typename
+                fusion::result_of::value_at_c<
+                    typename Component::elements_type, 2>::type
+            type;
+        };
+
+        template<typename Component, int N>
+        struct arg_c
+            : fusion::result_of::value_at_c<
+                    typename Component::elements_type, N>
+        {};
+
+    }
+
+    template <typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, 0>::type
+    inline subject(Component const& c)
+    {
+        return fusion::at_c<0>(c.elements);
+    }
+
+    template <typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, 0>::type
+    inline left(Component const& c)
+    {
+        return fusion::at_c<0>(c.elements);
+    }
+
+    template <typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, 1>::type
+    inline right(Component const& c)
+    {
+        return fusion::at_c<1>(c.elements);
+    }
+
+    template <typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, 1>::type
+    inline argument1(Component const& c)
+    {
+        return fusion::at_c<1>(c.elements);
+    }
+
+    template <typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, 2>::type
+    inline argument2(Component const& c)
+    {
+        return fusion::at_c<2>(c.elements);
+    }
+
+    template <int N, typename Component>
+    typename fusion::result_of::at_c<
+        typename Component::elements_type const, N>::type
+    inline arg_c(Component const& c)
+    {
+        return fusion::at_c<N>(c.elements);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Test if Expr conforms to the grammar of Domain. If Expr is already
+    //  a component, return mpl::true_.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace traits
+    {
+        template <typename Domain, typename Expr>
+        struct is_component
+          : proto::matches<
+                typename proto::result_of::as_expr<Expr>::type
+              , typename meta_grammar::grammar<Domain>::type
+            >
+        {
+        };
+
+        template <typename Domain, typename Director, typename Elements>
+        struct is_component<Domain, component<Domain, Director, Elements> > :
+            mpl::true_
+        {
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Convert an arbitrary expression to a spirit component. There's
+    //  a metafunction in namespace result_of and a function in main
+    //  spirit namespace. If Expr is already a component, return it as-is.
+    ///////////////////////////////////////////////////////////////////////////
+    namespace result_of
+    {
+        template <
+            typename Domain, typename Expr, typename State = unused_type, 
+            typename Visitor = unused_type
+        >
+        struct as_component
+        {
+            typedef typename meta_grammar::grammar<Domain>::type grammar;
+            typedef typename proto::result_of::as_expr<Expr>::type proto_xpr;
+
+            typedef typename
+                grammar::template result<
+                    void(proto_xpr, State, Visitor)
+                >::type
+            type;
+        };
+
+        // special case for arrays
+        template <
+            typename Domain, typename T, int N, 
+            typename State, typename Visitor>
+        struct as_component<Domain, T[N], State, Visitor>
+        {
+            typedef typename meta_grammar::grammar<Domain>::type grammar;
+            typedef typename proto::result_of::as_expr<T const*>::type proto_xpr;
+
+            typedef typename
+                grammar::template result<
+                    void(proto_xpr, State, Visitor)
+                >::type
+            type;
+        };
+
+        // special case for components
+        template <typename Domain, typename Director, typename Elements>
+        struct as_component<Domain, component<Domain, Director, Elements> > :
+            mpl::identity<component<Domain, Director, Elements> >
+        {
+        };
+    }
+
+    template <typename Domain, typename Expr>
+    inline typename result_of::as_component<Domain, Expr>::type
+    as_component(Domain, Expr const& xpr)
+    {
+        unused_type unused;
+        typedef typename result_of::as_component<Domain, Expr>::grammar grammar;
+        return grammar()(proto::as_expr(xpr), unused, unused);
+    };
+
+    template <typename Domain, typename Expr, typename State, typename Visitor>
+    inline typename result_of::as_component<Domain, Expr>::type
+    as_component(Domain, Expr const& xpr, State const& state, Visitor& visitor)
+    {
+        typedef typename 
+            result_of::as_component<Domain, Expr, State, Visitor>::grammar 
+        grammar;
+        return grammar()(proto::as_expr(xpr), state, visitor);
+    };
+
+    template <typename Domain, typename Director, typename Elements>
+    inline component<Domain, Director, Elements> const&
+    as_component(Domain, component<Domain, Director, Elements> const& component)
+    {
+        return component;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Create a component. This is a customization point. Components are
+    //  not created directly; they are created through make_component.
+    //  Clients may customize this to direct the creation of a component.
+    //
+    //  The extra Modifier template parameter may be used to direct the
+    //  creation of the component. This is the Visitor parameter in Proto
+    //  transforms.
+    //
+    //  (see also: modifier.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    namespace traits
+    {
+        template <
+            typename Domain, typename Director
+          , typename Elements, typename Modifier>
+        struct make_component
+          : mpl::identity<component<Domain, Director, Elements> >
+        {
+            static component<Domain, Director, Elements>
+            call(Elements const& elements)
+            {
+                return component<Domain, Director, Elements>(elements);
+            }
+        };
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/container.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,186 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_CONTAINER_FEB_06_2007_1001AM)
+#define BOOST_SPIRIT_CONTAINER_FEB_06_2007_1001AM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
+
+namespace boost { namespace spirit { namespace container
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  This file contains some container utils for stl containers. The
+    //  utilities provided also accept spirit's unused_type; all no-ops.
+    //  Compiler optimization will easily strip these away.
+    ///////////////////////////////////////////////////////////////////////////
+
+    namespace result_of 
+    {
+        template <typename Container>
+        struct value
+        {
+            typedef typename Container::value_type type;
+        };
+
+        template <>
+        struct value<unused_type>
+        {
+            typedef unused_type type;
+        };
+
+        template <>
+        struct value<unused_type const>
+        {
+            typedef unused_type type;
+        };
+
+        template <typename Container>
+        struct iterator
+        {
+            typedef typename Container::iterator type;
+        };
+        
+        template <typename Container>
+        struct iterator<Container const>
+        {
+            typedef typename Container::const_iterator type;
+        };
+        
+        template <>
+        struct iterator<unused_type>
+        {
+            typedef unused_type const* type;
+        };
+
+        template <>
+        struct iterator<unused_type const>
+        {
+            typedef unused_type const* type;
+        };
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Container, typename T>
+    inline void push_back(Container& c, T const& val)
+    {
+        c.push_back(val);
+    }
+
+    template <typename Container>
+    inline void push_back(Container&, unused_type)
+    {
+    }
+    
+    template <typename T>
+    inline void push_back(unused_type, T const&)
+    {
+    }
+    
+    inline void push_back(unused_type, unused_type)
+    {
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Container>
+    inline typename result_of::iterator<Container>::type
+    begin(Container& c)
+    {
+        return c.begin();
+    }
+    
+    template <typename Container>
+    inline typename result_of::iterator<Container const>::type
+    begin(Container const& c)
+    {
+        return c.begin();
+    }
+    
+    inline unused_type const*
+    begin(unused_type)
+    {
+        return &unused;
+    }
+    
+    template <typename Container>
+    inline typename result_of::iterator<Container>::type
+    end(Container& c)
+    {
+        return c.end();
+    }
+
+    template <typename Container>
+    inline typename result_of::iterator<Container const>::type
+    end(Container const& c)
+    {
+        return c.end();
+    }
+
+    inline unused_type const*
+    end(unused_type)
+    {
+        return &unused;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    inline typename boost::detail::iterator_traits<Iterator>::value_type
+    deref(Iterator& it)
+    {
+        return *it;
+    }
+    
+    inline unused_type
+    deref(unused_type*)
+    {
+        return unused;
+    }
+    
+    inline unused_type
+    deref(unused_type const*)
+    {
+        return unused;
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    inline Iterator
+    next(Iterator& it)
+    {
+        return ++it;
+    }
+    
+    inline unused_type
+    next(unused_type*)
+    {
+        return &unused;
+    }
+        
+    inline unused_type
+    next(unused_type const*)
+    {
+        return &unused;
+    }
+        
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Iterator>
+    inline bool
+    compare(Iterator const& it1, Iterator const& it2)
+    {
+        return it1 == it2;
+    }
+    
+    inline bool
+    compare(unused_type*, unused_type*)
+    {
+        return true;
+    }
+        
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/hold_any.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/hold_any.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,412 @@
+//  Copyright (c) 2008 Hartmut Kaiser
+//  Copyright (c) Christopher Diggins 2005
+//  Copyright (c) Pablo Aguilar 2005
+//  Copyright (c) Kevlin Henney 2001
+//
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The class boost::spirit::hold_any is built based on the any class
+//  published here: http://www.codeproject.com/cpp/dynamic_typing.asp. It adds
+//  support for std streaming operator<<() and operator>>().
+
+#if !defined(BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM)
+#define BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM
+
+#include <boost/config.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/assert.hpp>
+
+#include <stdexcept>
+#include <typeinfo>
+#include <algorithm>
+#include <iosfwd>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+    struct bad_any_cast
+      : std::bad_cast
+    {
+        bad_any_cast(std::type_info const& src, std::type_info const& dest)
+          : from(src.name()), to(dest.name())
+        {}
+
+        virtual const char* what() throw() { return "bad any cast"; }
+
+        const char* from;
+        const char* to;
+    };
+
+    namespace detail
+    {
+        // function pointer table
+        struct fxn_ptr_table
+        {
+            std::type_info const& (*get_type)();
+            void (*static_delete)(void**);
+            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*);
+        };
+
+        // static functions for small value-types
+        template<typename Small>
+        struct fxns;
+
+        template<>
+        struct fxns<mpl::true_>
+        {
+            template<typename T>
+            struct type
+            {
+                static std::type_info const& get_type()
+                {
+                    return typeid(T);
+                }
+                static void static_delete(void** x)
+                {
+                    reinterpret_cast<T*>(x)->~T();
+                }
+                static void destruct(void** x)
+                {
+                    reinterpret_cast<T*>(x)->~T();
+                }
+                static void clone(void* const* src, void** dest)
+                {
+                    new (dest) T(*reinterpret_cast<T const*>(src));
+                }
+                static void move(void* const* src, void** dest)
+                {
+                    reinterpret_cast<T*>(dest)->~T();
+                    *reinterpret_cast<T*>(dest) =
+                        *reinterpret_cast<T const*>(src);
+                }
+                static std::istream& stream_in (std::istream& i, void** obj)
+                {
+                    i >> *reinterpret_cast<T*>(obj);
+                    return i;
+                }
+                static std::ostream& stream_out(std::ostream& o, void* const* obj)
+                {
+                    o << *reinterpret_cast<T const*>(obj);
+                    return o;
+                }
+            };
+        };
+
+        // static functions for big value-types (bigger than a void*)
+        template<>
+        struct fxns<mpl::false_>
+        {
+            template<typename T>
+            struct type
+            {
+                static std::type_info const& get_type()
+                {
+                    return typeid(T);
+                }
+                static void static_delete(void** x)
+                {
+                    // destruct and free memory
+                    delete (*reinterpret_cast<T**>(x));
+                }
+                static void destruct(void** x)
+                {
+                    // destruct only, we'll reuse memory
+                    (*reinterpret_cast<T**>(x))->~T();
+                }
+                static void clone(void* const* src, void** dest)
+                {
+                    *dest = new T(**reinterpret_cast<T* const*>(src));
+                }
+                static void move(void* const* src, void** dest)
+                {
+                    (*reinterpret_cast<T**>(dest))->~T();
+                    **reinterpret_cast<T**>(dest) =
+                        **reinterpret_cast<T* const*>(src);
+                }
+                static std::istream& stream_in(std::istream& i, void** obj)
+                {
+                    i >> **reinterpret_cast<T**>(obj);
+                    return i;
+                }
+                static std::ostream& stream_out(std::ostream& o, void* const* obj)
+                {
+                    o << **reinterpret_cast<T* const*>(obj);
+                    return o;
+                }
+            };
+        };
+
+        template<typename T>
+        struct get_table
+        {
+            typedef mpl::bool_<(sizeof(T) <= sizeof(void*))> is_small;
+
+            static fxn_ptr_table* get()
+            {
+                static fxn_ptr_table 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
+                };
+                return &static_table;
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        struct empty {};
+
+        inline std::istream&
+        operator>> (std::istream& i, empty&)
+        {
+            // If this assertion fires you tried to insert from a std istream
+            // into an empty hold_any instance. This simply can't work, because
+            // there is no way to figure out what type to extract from the
+            // stream.
+            // The only way to make this work is to assign an arbitrary
+            // value of the required type to the hold_any instance you want to
+            // stream to. This assignment has to be executed before the actual
+            // call to the operator>>().
+            BOOST_ASSERT(false);
+            return i;
+        }
+
+        inline std::ostream&
+        operator<< (std::ostream& o, empty const&)
+        {
+            return o;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    class hold_any
+    {
+    public:
+        // constructors
+        template <typename T>
+        hold_any(T const& x)
+          : table(spirit::detail::get_table<T>::get()), object(0)
+        {
+            if (spirit::detail::get_table<T>::is_small::value)
+                new (&object) T(x);
+            else
+                object = new T(x);
+        }
+
+        hold_any()
+          : table(spirit::detail::get_table<spirit::detail::empty>::get()),
+            object(0)
+        {
+        }
+
+        hold_any(hold_any const& x)
+          : table(spirit::detail::get_table<spirit::detail::empty>::get()),
+            object(0)
+        {
+            assign(x);
+        }
+
+        ~hold_any()
+        {
+            table->static_delete(&object);
+        }
+
+        // assignment
+        hold_any& assign(hold_any const& x)
+        {
+            if (&x != this) {
+                // are we copying between the same type?
+                if (table == x.table) {
+                    // if so, we can avoid reallocation
+                    table->move(&x.object, &object);
+                }
+                else {
+                    reset();
+                    x.table->clone(&x.object, &object);
+                    table = x.table;
+                }
+            }
+            return *this;
+        }
+
+        template <typename T>
+        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();
+            if (table == x_table) {
+            // if so, we can avoid deallocating and re-use memory
+                table->destruct(&object);    // first destruct the old content
+                if (spirit::detail::get_table<T>::is_small::value) {
+                    // create copy on-top of object pointer itself
+                    new (&object) T(x);
+                }
+                else {
+                    // create copy on-top of old version
+                    new (object) T(x);
+                }
+            }
+            else {
+                if (spirit::detail::get_table<T>::is_small::value) {
+                    // create copy on-top of object pointer itself
+                    table->destruct(&object); // first destruct the old content
+                    new (&object) T(x); 
+                }
+                else {
+                    reset();                  // first delete the old content
+                    object = new T(x);
+                }
+                table = x_table;      // update table pointer
+            }
+            return *this;
+        }
+
+        // assignment operator
+        template <typename T>
+        hold_any& operator=(T const& x)
+        {
+            return assign(x);
+        }
+
+        // utility functions
+        hold_any& swap(hold_any& x)
+        {
+            std::swap(table, x.table);
+            std::swap(object, x.object);
+            return *this;
+        }
+
+        std::type_info const& type() const
+        {
+            return table->get_type();
+        }
+
+        template <typename T>
+        T const& cast() const
+        {
+            if (type() != typeid(T))
+              throw bad_any_cast(type(), typeid(T));
+
+            return spirit::detail::get_table<T>::is_small::value ?
+                *reinterpret_cast<T const*>(&object) :
+                *reinterpret_cast<T const*>(object);
+        }
+
+// implicit casting is disabled by default for compatibility with boost::any
+#ifdef BOOST_SPIRIT_ANY_IMPLICIT_CASTING
+        // automatic casting operator
+        template <typename T>
+        operator T const& () const { return cast<T>(); }
+#endif // implicit casting
+
+        bool empty() const
+        {
+            return table == spirit::detail::get_table<spirit::detail::empty>::get();
+        }
+
+        void reset()
+        {
+            if (!empty())
+            {
+                table->static_delete(&object);
+                table = spirit::detail::get_table<spirit::detail::empty>::get();
+                object = 0;
+            }
+        }
+
+    // these functions have been added in the assumption that the embedded
+    // type has a corresponding operator defined, which is completely safe
+    // because spirit::hold_any is used only in contexts where these operators
+    // do exist
+        friend std::istream& operator>> (std::istream& i, hold_any& obj)
+        {
+            return obj.table->stream_in(i, &obj.object);
+        }
+
+        friend std::ostream& operator<< (std::ostream& o, hold_any 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 *);
+#else
+    public: // types (public so any_cast can be non-friend)
+#endif
+        // fields
+        spirit::detail::fxn_ptr_table* table;
+        void* object;
+    };
+
+    // boost::any-like casting
+    template <typename T>
+    inline T* any_cast (hold_any* operand)
+    {
+        if (operand && operand->type() == typeid(T)) {
+            return spirit::detail::get_table<T>::is_small::value ?
+                reinterpret_cast<T*>(&operand->object) :
+                reinterpret_cast<T*>(operand->object);
+        }
+        return 0;
+    }
+
+    template <typename T>
+    inline T const* any_cast(hold_any const* operand)
+    {
+        return any_cast<T>(const_cast<hold_any*>(operand));
+    }
+
+    template <typename T>
+    T any_cast(hold_any& operand)
+    {
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // If 'nonref' is still reference type, it means the user has not
+        // specialized 'remove_reference'.
+
+        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
+        // to generate specialization of remove_reference for your class
+        // See type traits library documentation for details
+        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
+#endif
+
+        nonref* result = any_cast<nonref>(&operand);
+        if(!result)
+            boost::throw_exception(bad_any_cast(operand.type(), typeid(T)));
+        return *result;
+    }
+
+    template <typename T>
+    T const& any_cast(hold_any const& operand)
+    {
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
+
+#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+        // The comment in the above version of 'any_cast' explains when this
+        // assert is fired and what to do.
+        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
+#endif
+
+        return any_cast<nonref const&>(const_cast<hold_any &>(operand));
+    }
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/integer/cover_operators.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/integer/cover_operators.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,77 @@
+//  boost/integer/cover_operators.hpp ----------------------------------------//
+
+//  (C) Copyright Darin Adler 2000
+
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_INTEGER_COVER_OPERATORS_HPP
+#define BOOST_INTEGER_COVER_OPERATORS_HPP
+
+#include <boost/operators.hpp>
+#include <iosfwd>
+
+namespace boost
+{
+  namespace integer
+  {
+
+  // A class that adds integer operators to an integer cover class
+
+    template <typename T, typename IntegerType>
+    class cover_operators : boost::operators<T>
+    {
+      // The other operations take advantage of the type conversion that's
+      // built into unary +.
+
+      // Unary operations.
+      friend IntegerType operator+(const T& x) { return x; }
+      friend IntegerType operator-(const T& x) { return -+x; }
+      friend IntegerType operator~(const T& x) { return ~+x; }
+      friend IntegerType operator!(const T& x) { return !+x; }
+
+      // The basic ordering operations.
+      friend bool operator==(const T& x, IntegerType y) { return +x == y; }
+      friend bool operator<(const T& x, IntegerType y) { return +x < y; }
+      
+      // The basic arithmetic operations.
+      friend T& operator+=(T& x, IntegerType y) { return x = +x + y; }
+      friend T& operator-=(T& x, IntegerType y) { return x = +x - y; }
+      friend T& operator*=(T& x, IntegerType y) { return x = +x * y; }
+      friend T& operator/=(T& x, IntegerType y) { return x = +x / y; }
+      friend T& operator%=(T& x, IntegerType y) { return x = +x % y; }
+      friend T& operator&=(T& x, IntegerType y) { return x = +x & y; }
+      friend T& operator|=(T& x, IntegerType y) { return x = +x | y; }
+      friend T& operator^=(T& x, IntegerType y) { return x = +x ^ y; }
+      friend T& operator<<=(T& x, IntegerType y) { return x = +x << y; }
+      friend T& operator>>=(T& x, IntegerType y) { return x = +x >> y; }
+      
+      // A few binary arithmetic operations not covered by operators base class.
+      friend IntegerType operator<<(const T& x, IntegerType y) { return +x << y; }
+      friend IntegerType operator>>(const T& x, IntegerType y) { return +x >> y; }
+      
+      // Auto-increment and auto-decrement can be defined in terms of the
+      // arithmetic operations.
+      friend T& operator++(T& x) { return x += 1; }
+      friend T& operator--(T& x) { return x -= 1; }
+
+  /// TODO: stream I/O needs to be templatized on the stream type, so will
+  /// work with wide streams, etc.
+
+      // Stream input and output.
+      friend std::ostream& operator<<(std::ostream& s, const T& x)
+        { return s << +x; }
+      friend std::istream& operator>>(std::istream& s, T& x)
+        {
+          IntegerType i;
+          if (s >> i)
+            x = i;
+          return s;
+        }
+    };
+  } // namespace integer
+} // namespace boost
+
+#endif // BOOST_INTEGER_COVER_OPERATORS_HPP
Added: trunk/boost/spirit/home/support/detail/integer/endian.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/integer/endian.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,338 @@
+//  Boost endian.hpp header file (proposed) ----------------------------------//
+
+//  (C) Copyright Darin Adler 2000
+//  (C) Copyright Beman Dawes 2006
+
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See library home page at http://www.boost.org/libs/endian
+
+//----------------------------------------------------------------------------//
+
+//  Original design developed by Darin Adler based on classes developed by Mark
+//  Borgerding. Four original class templates combined into a single endian
+//  class template by Beman Dawes, who also added the unrolled_byte_loops sign
+//  partial specialization to correctly extend the sign when cover integer size
+//  differs from endian representation size.
+
+#ifndef BOOST_ENDIAN_HPP
+#define BOOST_ENDIAN_HPP
+
+#include <boost/detail/endian.hpp>
+#include <boost/spirit/home/support/detail/integer/cover_operators.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <iosfwd>
+#include <climits>
+
+# if CHAR_BIT != 8
+#   error Platforms with CHAR_BIT != 8 are not supported
+# endif
+
+namespace boost
+{
+  namespace detail
+  {
+    // Unrolled loops for loading and storing streams of bytes.
+
+    template <typename T, std::size_t n_bytes,
+      bool sign=boost::is_signed<T>::value >
+    struct unrolled_byte_loops
+    {
+      typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
+
+      static T load_big(const unsigned char* bytes)
+        { return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
+      static T load_little(const unsigned char* bytes)
+        { return *bytes | (next::load_little(bytes + 1) << 8); }
+
+      static void store_big(char* bytes, T value)
+        {
+          *(bytes - 1) = static_cast<char>(value);
+          next::store_big(bytes - 1, value >> 8);
+        }
+      static void store_little(char* bytes, T value)
+        {
+          *bytes = static_cast<char>(value);
+          next::store_little(bytes + 1, value >> 8);
+        }
+    };
+
+    template <typename T>
+    struct unrolled_byte_loops<T, 1, false>
+    {
+      static T load_big(const unsigned char* bytes)
+        { return *(bytes - 1); }
+      static T load_little(const unsigned char* bytes)
+        { return *bytes; }
+      static void store_big(char* bytes, T value)
+        { *(bytes - 1) = static_cast<char>(value); }
+      static void store_little(char* bytes, T value)
+        { *bytes = static_cast<char>(value); }
+
+    };
+
+    template <typename T>
+    struct unrolled_byte_loops<T, 1, true>
+    {
+      static T load_big(const unsigned char* bytes)
+        { return *reinterpret_cast<const signed char*>(bytes - 1); }
+      static T load_little(const unsigned char* bytes)
+        { return *reinterpret_cast<const signed char*>(bytes); }
+      static void store_big(char* bytes, T value)
+        { *(bytes - 1) = static_cast<char>(value); }
+      static void store_little(char* bytes, T value)
+        { *bytes = static_cast<char>(value); }
+    };
+
+    template <typename T, std::size_t n_bytes>
+    inline
+    T load_big_endian(const void* bytes)
+    {
+      return unrolled_byte_loops<T, n_bytes>::load_big
+        (static_cast<const unsigned char*>(bytes) + n_bytes);
+    }
+
+    template <typename T, std::size_t n_bytes>
+    inline
+    T load_little_endian(const void* bytes)
+    {
+      return unrolled_byte_loops<T, n_bytes>::load_little
+        (static_cast<const unsigned char*>(bytes));
+    }
+
+    template <typename T, std::size_t n_bytes>
+    inline
+    void store_big_endian(void* bytes, T value)
+    {
+      unrolled_byte_loops<T, n_bytes>::store_big
+        (static_cast<char*>(bytes) + n_bytes, value);
+    }
+
+    template <typename T, std::size_t n_bytes>
+    inline
+    void store_little_endian(void* bytes, T value)
+    {
+      unrolled_byte_loops<T, n_bytes>::store_little
+        (static_cast<char*>(bytes), value);
+    }
+
+  } // namespace detail
+
+  namespace integer
+  {
+
+  //  endian class template and specializations  -----------------------------//
+
+    enum endianness { big, little, native };
+
+    enum alignment { unaligned, aligned };
+
+    template <endianness E, typename T, std::size_t n_bits,
+      alignment A = unaligned>
+    class endian;
+
+    //  Specializations that represent unaligned bytes.
+    //  Taking an integer type as a parameter provides a nice way to pass both
+    //  the size and signedness of the desired integer and get the appropriate
+    //  corresponding integer type for the interface.
+
+    template <typename T, std::size_t n_bits>
+    class endian< big, T, n_bits, unaligned >
+      : cover_operators< endian< big, T, n_bits >, T >
+    {
+        BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
+      public:
+        typedef T value_type;
+        endian() {}
+        endian(T i) { detail::store_big_endian<T, n_bits/8>(bytes, i); }
+        operator T() const 
+          { return detail::load_big_endian<T, n_bits/8>(bytes); }
+      private:
+  	    char bytes[n_bits/8];
+    };
+
+    template <typename T, std::size_t n_bits>
+    class endian< little, T, n_bits, unaligned >
+      : cover_operators< endian< little, T, n_bits >, T >
+    {
+        BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
+      public:
+        typedef T value_type;
+        endian() {}
+        endian(T i) { detail::store_little_endian<T, n_bits/8>(bytes, i); }
+        operator T() const
+          { return detail::load_little_endian<T, n_bits/8>(bytes); }
+      private:
+  	    char bytes[n_bits/8];
+    };
+
+    template <typename T, std::size_t n_bits>
+    class endian< native, T, n_bits, unaligned >
+      : cover_operators< endian< native, T, n_bits >, T >
+    {
+        BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
+      public:
+        typedef T value_type;
+        endian() {}
+#     ifdef BOOST_BIG_ENDIAN
+        endian(T i) { detail::store_big_endian<T, n_bits/8>(bytes, i); }
+        operator T() const
+          { return detail::load_big_endian<T, n_bits/8>(bytes); }
+#     else
+        endian(T i) { detail::store_little_endian<T, n_bits/8>(bytes, i); }
+        operator T() const
+          { return detail::load_little_endian<T, n_bits/8>(bytes); }
+#     endif
+      private:
+  	    char bytes[n_bits/8];
+    };
+
+    //  Specializations that mimic built-in integer types.
+    //  These typically have the same alignment as the underlying types.
+
+    template <typename T, std::size_t n_bits>
+    class endian< big, T, n_bits, aligned  >
+      : cover_operators< endian< big, T, n_bits, aligned >, T >
+    {
+        BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
+        BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
+      public:
+        typedef T value_type;
+        endian() {}
+    #ifdef BOOST_BIG_ENDIAN
+        endian(T i) : integer(i) { }
+        operator T() const { return integer; }
+    #else
+        endian(T i) { detail::store_big_endian<T, sizeof(T)>(&integer, i); }
+        operator T() const
+          { return detail::load_big_endian<T, sizeof(T)>(&integer); }
+    #endif
+      private:
+  	    T integer;
+    };
+
+    template <typename T, std::size_t n_bits>
+    class endian< little, T, n_bits, aligned  >
+      : cover_operators< endian< little, T, n_bits, aligned >, T >
+    {
+        BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
+        BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
+      public:
+        typedef T value_type;
+        endian() {}
+    #ifdef BOOST_LITTLE_ENDIAN
+        endian(T i) : integer(i) { }
+        operator T() const { return integer; }
+    #else
+        endian(T i)
+          { detail::store_little_endian<T, sizeof(T)>(&integer, i); }
+        operator T() const
+          { return detail::load_little_endian<T, sizeof(T)>(&integer); }
+    #endif
+      private:
+  	    T integer;
+    };
+
+  //  naming convention typedefs  --------------------------------------------//
+
+    // unaligned big endian signed integer types
+    typedef endian< big, int_least8_t, 8 >           big8_t;
+    typedef endian< big, int_least16_t, 16 >         big16_t;
+    typedef endian< big, int_least32_t, 24 >         big24_t;
+    typedef endian< big, int_least32_t, 32 >         big32_t;
+    typedef endian< big, int_least64_t, 40 >         big40_t;
+    typedef endian< big, int_least64_t, 48 >         big48_t;
+    typedef endian< big, int_least64_t, 56 >         big56_t;
+    typedef endian< big, int_least64_t, 64 >         big64_t;
+
+    // unaligned big endian unsigned integer types
+    typedef endian< big, uint_least8_t, 8 >          ubig8_t;
+    typedef endian< big, uint_least16_t, 16 >        ubig16_t;
+    typedef endian< big, uint_least32_t, 24 >        ubig24_t;
+    typedef endian< big, uint_least32_t, 32 >        ubig32_t;
+    typedef endian< big, uint_least64_t, 40 >        ubig40_t;
+    typedef endian< big, uint_least64_t, 48 >        ubig48_t;
+    typedef endian< big, uint_least64_t, 56 >        ubig56_t;
+    typedef endian< big, uint_least64_t, 64 >        ubig64_t;
+
+    // unaligned little endian signed integer types
+    typedef endian< little, int_least8_t, 8 >        little8_t;
+    typedef endian< little, int_least16_t, 16 >      little16_t;
+    typedef endian< little, int_least32_t, 24 >      little24_t;
+    typedef endian< little, int_least32_t, 32 >      little32_t;
+    typedef endian< little, int_least64_t, 40 >      little40_t;
+    typedef endian< little, int_least64_t, 48 >      little48_t;
+    typedef endian< little, int_least64_t, 56 >      little56_t;
+    typedef endian< little, int_least64_t, 64 >      little64_t;
+
+    // unaligned little endian unsigned integer types
+    typedef endian< little, uint_least8_t, 8 >       ulittle8_t;
+    typedef endian< little, uint_least16_t, 16 >     ulittle16_t;
+    typedef endian< little, uint_least32_t, 24 >     ulittle24_t;
+    typedef endian< little, uint_least32_t, 32 >     ulittle32_t;
+    typedef endian< little, uint_least64_t, 40 >     ulittle40_t;
+    typedef endian< little, uint_least64_t, 48 >     ulittle48_t;
+    typedef endian< little, uint_least64_t, 56 >     ulittle56_t;
+    typedef endian< little, uint_least64_t, 64 >     ulittle64_t;
+
+    // unaligned native endian signed integer types
+    typedef endian< native, int_least8_t, 8 >        native8_t;
+    typedef endian< native, int_least16_t, 16 >      native16_t;
+    typedef endian< native, int_least32_t, 24 >      native24_t;
+    typedef endian< native, int_least32_t, 32 >      native32_t;
+    typedef endian< native, int_least64_t, 40 >      native40_t;
+    typedef endian< native, int_least64_t, 48 >      native48_t;
+    typedef endian< native, int_least64_t, 56 >      native56_t;
+    typedef endian< native, int_least64_t, 64 >      native64_t;
+
+    // unaligned native endian unsigned integer types
+    typedef endian< native, uint_least8_t, 8 >       unative8_t;
+    typedef endian< native, uint_least16_t, 16 >     unative16_t;
+    typedef endian< native, uint_least32_t, 24 >     unative24_t;
+    typedef endian< native, uint_least32_t, 32 >     unative32_t;
+    typedef endian< native, uint_least64_t, 40 >     unative40_t;
+    typedef endian< native, uint_least64_t, 48 >     unative48_t;
+    typedef endian< native, uint_least64_t, 56 >     unative56_t;
+    typedef endian< native, uint_least64_t, 64 >     unative64_t;
+
+#define BOOST_HAS_INT16_T
+#define BOOST_HAS_INT32_T
+#define BOOST_HAS_INT64_T
+  
+  //  These types only present if platform has exact size integers:
+  //     aligned big endian signed integer types
+  //     aligned big endian unsigned integer types
+  //     aligned little endian signed integer types
+  //     aligned little endian unsigned integer types
+
+  //     aligned native endian typedefs are not provided because
+  //     <cstdint> types are superior for this use case
+
+# if defined(BOOST_HAS_INT16_T)
+    typedef endian< big, int16_t, 16, aligned >      aligned_big16_t;
+    typedef endian< big, uint16_t, 16, aligned >     aligned_ubig16_t;
+    typedef endian< little, int16_t, 16, aligned >   aligned_little16_t;
+    typedef endian< little, uint16_t, 16, aligned >  aligned_ulittle16_t;
+# endif
+
+# if defined(BOOST_HAS_INT32_T)
+    typedef endian< big, int32_t, 32, aligned >      aligned_big32_t;
+    typedef endian< big, uint32_t, 32, aligned >     aligned_ubig32_t;
+    typedef endian< little, int32_t, 32, aligned >   aligned_little32_t;
+    typedef endian< little, uint32_t, 32, aligned >  aligned_ulittle32_t;
+# endif
+
+# if defined(BOOST_HAS_INT64_T)
+    typedef endian< big, int64_t, 64, aligned >      aligned_big64_t;
+    typedef endian< big, uint64_t, 64, aligned >     aligned_ubig64_t;
+    typedef endian< little, int64_t, 64, aligned >   aligned_little64_t;
+    typedef endian< little, uint64_t, 64, aligned >  aligned_ulittle64_t;
+# endif
+
+  } // namespace integer
+} // namespace boost
+
+#endif // BOOST_ENDIAN_HPP
Added: trunk/boost/spirit/home/support/detail/lexer/char_state_machine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/char_state_machine.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,62 @@
+// char_state_machine.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_CHAR_STATE_MACHINE_HPP
+#define BOOST_LEXER_CHAR_STATE_MACHINE_HPP
+
+#include "consts.hpp"
+#include <map>
+#include "size_t.hpp"
+#include "string_token.hpp"
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+template<typename CharT>
+struct basic_char_state_machine
+{
+    struct state
+    {
+        typedef basic_string_token<CharT> string_token;
+        typedef std::map<std::size_t, string_token> size_t_string_token_map;
+        typedef std::pair<std::size_t, string_token> size_t_string_token_pair;
+
+        bool _end_state;
+        std::size_t _id;
+        std::size_t _state;
+        std::size_t _bol_index;
+        std::size_t _eol_index;
+        size_t_string_token_map _transitions;
+
+        state () :
+            _end_state (false),
+            _id (0),
+            _state (0),
+            _bol_index (npos),
+            _eol_index (npos)
+        {
+        }
+    };
+
+    typedef std::vector<state> state_vector;
+    typedef std::vector<state_vector> state_vector_vector;
+
+    state_vector_vector _sm_vector;
+
+    void clear ()
+    {
+        _sm_vector.clear ();
+    }
+};
+
+typedef basic_char_state_machine<char> char_state_machine;
+typedef basic_char_state_machine<wchar_t> wchar_state_machine;
+
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/char_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/char_traits.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,36 @@
+// char_traits.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_CHAR_TRAITS_H
+#define BOOST_LEXER_CHAR_TRAITS_H
+
+// Make sure wchar_t is defined
+#include <string>
+
+namespace boost
+{
+namespace lexer
+{
+template<typename CharT>
+struct char_traits
+{
+    typedef CharT index_type;
+};
+
+template<>
+struct char_traits<char>
+{
+    typedef unsigned char index_type;
+};
+
+template<>
+struct char_traits<wchar_t>
+{
+    typedef wchar_t index_type;
+};
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/consts.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/consts.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,32 @@
+// consts.h
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_CONSTS_H
+#define BOOST_LEXER_CONSTS_H
+
+#include "size_t.hpp"
+#include <wchar.h>
+
+namespace boost
+{
+namespace lexer
+{
+    // 0 = end state, 1 = id, 2 = lex state, 3 = bol, 4 = eol
+    // 5 = dead_state_index
+    enum {end_state_index, id_index, state_index, bol_index, eol_index,
+        dead_state_index, dfa_offset};
+
+    const std::size_t max_macro_len = 20;
+    const std::size_t num_chars = 256;
+    const std::size_t num_wchar_ts = WCHAR_MAX < 0x110000 ? WCHAR_MAX : 0x110000;
+    const std::size_t null_token = static_cast<std::size_t> (~0);
+    const std::size_t bol_token = static_cast<std::size_t> (~1);
+    const std::size_t eol_token = static_cast<std::size_t> (~2);
+    const std::size_t end_state = 1;
+    const std::size_t npos = static_cast<std::size_t> (~0);
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/containers/ptr_list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/containers/ptr_list.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,71 @@
+// ptr_list.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_PTR_LIST_HPP
+#define BOOST_LEXER_PTR_LIST_HPP
+
+#include <list>
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename Type>
+class ptr_list
+{
+public:
+    typedef std::list<Type *> list;
+
+    ptr_list ()
+    {
+    }
+
+    ~ptr_list ()
+    {
+        clear ();
+    }
+
+    list *operator -> ()
+    {
+        return &_list;
+    }
+
+    const list *operator -> () const
+    {
+        return &_list;
+    }
+
+    list &operator * ()
+    {
+        return _list;
+    }
+
+    const list &operator * () const
+    {
+        return _list;
+    }
+
+    void clear ()
+    {
+        while (!_list.empty ())
+        {
+            delete _list.front ();
+            _list.pop_front ();
+        }
+    }
+
+private:
+    list _list;
+
+    ptr_list (ptr_list const &); // No copy construction.
+    ptr_list &operator = (ptr_list const &); // No assignment.
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/containers/ptr_vector.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/containers/ptr_vector.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,89 @@
+// ptr_vector.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_PTR_VECTOR_HPP
+#define BOOST_LEXER_PTR_VECTOR_HPP
+
+#include "../size_t.hpp"
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename Type>
+class ptr_vector
+{
+public:
+    typedef std::vector<Type *> vector;
+
+    ptr_vector ()
+    {
+    }
+
+    ~ptr_vector ()
+    {
+        clear ();
+    }
+
+    vector *operator -> ()
+    {
+        return &_vector;
+    }
+
+    const vector *operator -> () const
+    {
+        return &_vector;
+    }
+
+    vector &operator * ()
+    {
+        return _vector;
+    }
+
+    const vector &operator * () const
+    {
+        return _vector;
+    }
+
+    Type * &operator [] (const std::size_t index_)
+    {
+        return _vector[index_];
+    }
+
+    Type * const &operator [] (const std::size_t index_) const
+    {
+        return _vector[index_];
+    }
+
+    void clear ()
+    {
+        if (!_vector.empty ())
+        {
+            Type **iter_ = &_vector.front ();
+            Type **end_ = iter_ + _vector.size ();
+
+            for (; iter_ != end_; ++iter_)
+            {
+                delete *iter_;
+            }
+        }
+
+        _vector.clear ();
+    }
+
+private:
+    vector _vector;
+
+    ptr_vector (ptr_vector const &); // No copy construction.
+    ptr_vector &operator = (ptr_vector const &); // No assignment.
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/debug.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/debug.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,291 @@
+// debug.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_DEBUG_HPP
+#define BOOST_LEXER_DEBUG_HPP
+
+#include <map>
+#include <ostream>
+#include "size_t.hpp"
+#include "state_machine.hpp"
+#include "string_token.hpp"
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+template<typename CharT>
+class basic_debug
+{
+public:
+    typedef std::basic_ostream<CharT> ostream;
+    typedef std::basic_string<CharT> string;
+    typedef std::vector<std::size_t> size_t_vector;
+
+    static void escape_control_chars (const string &in_, string &out_)
+    {
+        const CharT *ptr_ = in_.c_str ();
+        std::size_t size_ = in_.size ();
+
+#if defined _MSC_VER && _MSC_VER <= 1200
+        out_.erase ();
+#else
+        out_.clear ();
+#endif
+
+        while (size_)
+        {
+            switch (*ptr_)
+            {
+                case '\0':
+                    out_ += '\\';
+                    out_ += '0';
+                    break;
+                case '\a':
+                    out_ += '\\';
+                    out_ += 'a';
+                    break;
+                case '\b':
+                    out_ += '\\';
+                    out_ += 'b';
+                    break;
+                case 27:
+                    out_ += '\\';
+                    out_ += 'x';
+                    out_ += '1';
+                    out_ += 'b';
+                    break;
+                case '\f':
+                    out_ += '\\';
+                    out_ += 'f';
+                    break;
+                case '\n':
+                    out_ += '\\';
+                    out_ += 'n';
+                    break;
+                case '\r':
+                    out_ += '\\';
+                    out_ += 'r';
+                    break;
+                case '\t':
+                    out_ += '\\';
+                    out_ += 't';
+                    break;
+                case '\v':
+                    out_ += '\\';
+                    out_ += 'v';
+                    break;
+                case '\\':
+                    out_ += '\\';
+                    out_ += '\\';
+                    break;
+                case '"':
+                    out_ += '\\';
+                    out_ += '"';
+                    break;
+                default:
+                {
+                    if (*ptr_ < 32 && *ptr_ >= 0)
+                    {
+                        stringstream ss_;
+
+                        out_ += '\\';
+                        out_ += 'x';
+                        ss_ << std::hex <<
+                            static_cast<std::size_t> (*ptr_);
+                        out_ += ss_.str ();
+                    }
+                    else
+                    {
+                        out_ += *ptr_;
+                    }
+
+                    break;
+                }
+            }
+
+            ++ptr_;
+            --size_;
+        }
+    }
+
+    static void dump (const state_machine &state_machine_, ostream &stream_)
+    {
+        basic_char_state_machine<CharT> char_state_machine_;
+
+        state_machine_.human_readable (char_state_machine_);
+
+        for (std::size_t state_ = 0,
+            states_ = char_state_machine_._sm_vector.size ();
+            state_ < states_; ++state_)
+        {
+            const typename basic_char_state_machine<CharT>::state *ptr_ =
+                &char_state_machine_._sm_vector[state_].front ();
+            const std::size_t size_ = char_state_machine_.
+                _sm_vector[state_].size ();
+
+            for (std::size_t i_ = 0; i_ < size_; ++i_, ++ptr_)
+            {
+                state (stream_);
+                stream_ << i_ << std::endl;
+
+                if (ptr_->_end_state)
+                {
+                    end_state (stream_);
+                    stream_ << ptr_->_id;
+                    dfa (stream_);
+                    stream_ << ptr_->_state;
+                    stream_ << std::endl;
+                }
+
+                if (ptr_->_bol_index != npos)
+                {
+                    bol (stream_);
+                    stream_ << ptr_->_bol_index << std::endl;
+                }
+
+                if (ptr_->_eol_index != npos)
+                {
+                    eol (stream_);
+                    stream_ << ptr_->_eol_index << std::endl;
+                }
+
+                for (typename basic_char_state_machine<CharT>::state::
+                    size_t_string_token_map::const_iterator iter_ = ptr_->
+                    _transitions.begin (), end_ = ptr_->_transitions.end ();
+                    iter_ != end_; ++iter_)
+                {
+                    std::size_t transition_ = iter_->first;
+
+                    if (iter_->second.any ())
+                    {
+                        any (stream_);
+                    }
+                    else
+                    {
+                        open_bracket (stream_);
+
+                        if (iter_->second._negated)
+                        {
+                            negated (stream_);
+                        }
+
+                        string charset_;
+
+                        escape_control_chars (iter_->second._charset,
+                            charset_);
+                        stream_ << charset_;
+                        close_bracket (stream_);
+                    }
+
+                    stream_ << transition_ << std::endl;
+                }
+
+                stream_ << std::endl;
+            }
+        }
+    }
+
+protected:
+    typedef std::basic_stringstream<CharT> stringstream;
+
+    static void state (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "State: ";
+    }
+
+    static void state (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"State: ";
+    }
+
+    static void bol (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "  BOL -> ";
+    }
+
+    static void bol (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"  BOL -> ";
+    }
+
+    static void eol (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "  EOL -> ";
+    }
+
+    static void eol (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"  EOL -> ";
+    }
+
+    static void end_state (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "  END STATE, Id = ";
+    }
+
+    static void end_state (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"  END STATE, Id = ";
+    }
+
+    static void any (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "  . -> ";
+    }
+
+    static void any (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"  . -> ";
+    }
+
+    static void open_bracket (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "  [";
+    }
+
+    static void open_bracket (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"  [";
+    }
+
+    static void negated (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "^";
+    }
+
+    static void negated (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"^";
+    }
+
+    static void close_bracket (std::basic_ostream<char> &stream_)
+    {
+        stream_ << "] -> ";
+    }
+
+    static void close_bracket (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L"] -> ";
+    }
+
+    static void dfa (std::basic_ostream<char> &stream_)
+    {
+        stream_ << ", dfa = ";
+    }
+
+    static void dfa (std::basic_ostream<wchar_t> &stream_)
+    {
+        stream_ << L", dfa = ";
+    }
+};
+
+typedef basic_debug<char> debug;
+typedef basic_debug<wchar_t> wdebug;
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/generate_cpp.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/generate_cpp.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,536 @@
+// cpp_code.hpp
+// Copyright (c) 2008 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_EXAMPLE_CPP_CODE_HPP
+#define BOOST_LEXER_EXAMPLE_CPP_CODE_HPP
+
+#include "char_traits.hpp"
+#include "consts.hpp"
+#include <iostream>
+#include <boost/detail/iterator.hpp>
+#include "runtime_error.hpp"
+#include "size_t.hpp"
+#include "state_machine.hpp"
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+void generate_cpp (const state_machine &sm_, std::ostream &os_,
+    const bool use_pointers_ = false, const bool skip_unknown_ = true,
+    const bool optimise_parameters_ = true, const char *name_ = "next_token")
+{
+    if (sm_._lookup->size () == 0)
+    {
+        throw runtime_error ("Cannot generate code from an empty state machine");
+    }
+
+    std::string upper_name_ (__DATE__);
+    const std::size_t lookups_ = sm_._lookup->front ()->size ();
+    const std::size_t dfas_ = sm_._dfa->size ();
+    std::string::size_type pos_ = upper_name_.find (' ');
+    const char *iterator_ = 0;
+
+    if (use_pointers_)
+    {
+        if (lookups_ == 256)
+        {
+            iterator_ = "const char *";
+        }
+        else
+        {
+            iterator_ = "const wchar_t *";
+        }
+    }
+    else
+    {
+        iterator_ = "Iterator &";
+    }
+
+    while (pos_ != std::string::npos)
+    {
+        upper_name_.replace (pos_, 1, "_");
+        pos_ = upper_name_.find (' ', pos_);
+    }
+
+    upper_name_ += '_';
+    upper_name_ +=  __TIME__;
+
+    pos_ = upper_name_.find (':');
+
+    while (pos_ != std::string::npos)
+    {
+        upper_name_.erase (pos_, 1);
+        pos_ = upper_name_.find (':', pos_);
+    }
+
+    upper_name_ = '_' + upper_name_;
+    upper_name_ = name_ + upper_name_;
+    std::transform (upper_name_.begin (), upper_name_.end (),
+        upper_name_.begin (), ::toupper);
+    os_ << "#ifndef " << upper_name_ + '\n';
+    os_ << "#define " << upper_name_ + '\n';
+    os_ << "// Copyright (c) 2008 Ben Hanson\n";
+    os_ << "//\n";
+    os_ << "// Distributed under the Boost Software License, "
+        "Version 1.0. (See accompanying\n";
+    os_ << "// file licence_1_0.txt or copy at "
+        "http://www.boost.org/LICENSE_1_0.txt)\n\n";
+    os_ << "// Auto-generated by boost::lexer\n";
+    os_ << "template<typename Iterator>\n";
+    os_ << "std::size_t " << name_  << " (";
+
+    if (dfas_ > 1 || !optimise_parameters_)
+    {
+        os_ << "std::size_t &start_state_, ";
+    }
+
+    if (sm_._seen_BOL_assertion || !optimise_parameters_)
+    {
+        if (use_pointers_)
+        {
+            os_ << iterator_ << " const ";
+        }
+        else
+        {
+            os_ << "const " << iterator_;
+        }
+
+        os_ << "start_, ";
+    }
+
+    if (dfas_ > 1 || sm_._seen_BOL_assertion || !optimise_parameters_)
+    {
+        os_ << "\n    ";
+    }
+
+    if (use_pointers_)
+    {
+        os_ << iterator_ << " &";
+    }
+    else
+    {
+        os_ << iterator_;
+    }
+
+    os_ << "start_token_, ";
+
+    if (use_pointers_)
+    {
+        os_ << iterator_ << " const ";
+    }
+    else
+    {
+        os_ << "const " << iterator_;
+    }
+
+    os_ << "end_)\n";
+    os_ << "{\n";
+    os_ << "    enum {end_state_index, id_index, state_index, bol_index, "
+        "eol_index,\n";
+    os_ << "        dead_state_index, dfa_offset};\n";
+    os_ << "    static const std::size_t npos = static_cast"
+        "<std::size_t>(~0);\n";
+
+    if (dfas_ > 1)
+    {
+        std::size_t state_ = 0;
+
+        for (; state_ < dfas_; ++state_)
+        {
+            std::size_t i_ = 0;
+            std::size_t j_ = 1;
+            std::size_t count_ = lookups_ / 8;
+            const std::size_t *lookup_ = &sm_._lookup[state_]->front ();
+            const std::size_t *dfa_ = &sm_._dfa[state_]->front ();
+
+            os_ << "    static const std::size_t lookup" << state_ << "_[" <<
+                lookups_ << "] = {";
+
+            for (; i_ < count_; ++i_)
+            {
+                const std::size_t index_ = i_ * 8;
+
+                os_ << lookup_[index_];
+
+                for (; j_ < 8; ++j_)
+                {
+                    os_ << ", " << lookup_[index_ + j_];
+                }
+
+                if (i_ < count_ - 1)
+                {
+                    os_ << "," << std::endl << "        ";
+                }
+
+                j_ = 1;
+            }
+
+            os_ << "};\n";
+            count_ = sm_._dfa[state_]->size ();
+            os_ << "    static const std::size_t dfa" << state_ << "_[" <<
+                count_ << "] = {";
+            count_ /= 8;
+
+            for (i_ = 0; i_ < count_; ++i_)
+            {
+                const std::size_t index_ = i_ * 8;
+
+                os_ << dfa_[index_];
+
+                for (j_ = 1; j_ < 8; ++j_)
+                {
+                    os_ << ", " << dfa_[index_ + j_];
+                }
+
+                if (i_ < count_ - 1)
+                {
+                    os_ << "," << std::endl << "        ";
+                }
+            }
+
+            const std::size_t mod_ = sm_._dfa[state_]->size () % 8;
+
+            if (mod_)
+            {
+                const std::size_t index_ = count_ * 8;
+
+                if (count_)
+                {
+                    os_ << ",\n        ";
+                }
+
+                os_ << dfa_[index_];
+
+                for (j_ = 1; j_ < mod_; ++j_)
+                {
+                    os_ << ", " << dfa_[index_ + j_];
+                }
+            }
+
+            os_ << "};\n";
+        }
+
+        std::size_t count_ = sm_._dfa_alphabet.size ();
+        std::size_t i_ = 1;
+
+        os_ << "    static const std::size_t *lookup_arr_[" << count_ <<
+            "] = {";
+        os_ << "lookup0_";
+
+        for (i_ = 1; i_ < count_; ++i_)
+        {
+            os_ << ", " << "lookup" << i_ << "_";
+        }
+
+        os_ << "};\n";
+        os_ << "    static const std::size_t dfa_alphabet_arr_[" << count_ <<
+            "] = {";
+        os_ << sm_._dfa_alphabet.front ();
+
+        for (i_ = 1; i_ < count_; ++i_)
+        {
+            os_ << ", " << sm_._dfa_alphabet[i_];
+        }
+
+        os_ << "};\n";
+        os_ << "    static const std::size_t *dfa_arr_[" << count_ <<
+            "] = {";
+        os_ << "dfa0_";
+
+        for (i_ = 1; i_ < count_; ++i_)
+        {
+            os_ << ", " << "dfa" << i_ << "_";
+        }
+
+        os_ << "};\n";
+    }
+    else
+    {
+        const std::size_t *lookup_ = &sm_._lookup[0]->front ();
+        const std::size_t *dfa_ = &sm_._dfa[0]->front ();
+        std::size_t i_ = 0;
+        std::size_t j_ = 1;
+        std::size_t count_ = lookups_ / 8;
+
+        os_ << "    static const std::size_t lookup_[";
+        os_ << sm_._lookup[0]->size () << "] = {";
+
+        for (; i_ < count_; ++i_)
+        {
+            const std::size_t index_ = i_ * 8;
+
+            os_ << lookup_[index_];
+
+            for (; j_ < 8; ++j_)
+            {
+                os_ << ", " << lookup_[index_ + j_];
+            }
+
+            if (i_ < count_ - 1)
+            {
+                os_ << "," << std::endl << "        ";
+            }
+
+            j_ = 1;
+        }
+
+        os_ << "};\n";
+        os_ << "    static const std::size_t dfa_alphabet_ = " <<
+            sm_._dfa_alphabet.front () << ";\n";
+        os_ << "    static const std::size_t dfa_[" <<
+            sm_._dfa[0]->size () << "] = {";
+        count_ = sm_._dfa[0]->size () / 8;
+
+        for (i_ = 0; i_ < count_; ++i_)
+        {
+            const std::size_t index_ = i_ * 8;
+
+            os_ << dfa_[index_];
+
+            for (j_ = 1; j_ < 8; ++j_)
+            {
+                os_ << ", " << dfa_[index_ + j_];
+            }
+
+            if (i_ < count_ - 1)
+            {
+                os_ << "," << std::endl << "        ";
+            }
+        }
+
+        const std::size_t mod_ = sm_._dfa[0]->size () % 8;
+
+        if (mod_)
+        {
+            const std::size_t index_ = count_ * 8;
+
+            if (count_)
+            {
+                os_ << ",\n        ";
+            }
+
+            os_ << dfa_[index_];
+
+            for (j_ = 1; j_ < mod_; ++j_)
+            {
+                os_ << ", " << dfa_[index_ + j_];
+            }
+        }
+
+        os_ << "};\n";
+    }
+
+    os_ << "\n    if (start_token_ == end_) return 0;\n\n";
+
+    if (dfas_ > 1)
+    {
+        os_ << "again:\n";
+        os_ << "    const std::size_t * lookup_ = lookup_arr_[start_state_];\n";
+        os_ << "    std::size_t dfa_alphabet_ = dfa_alphabet_arr_[start_state_];\n";
+        os_ << "    const std::size_t *dfa_ = dfa_arr_[start_state_];\n";
+    }
+
+    os_ << "    const std::size_t *ptr_ = dfa_ + dfa_alphabet_;\n";
+    os_ << "    Iterator curr_ = start_token_;\n";
+    os_ << "    bool end_state_ = *ptr_ != 0;\n";
+    os_ << "    std::size_t id_ = *(ptr_ + id_index);\n";
+    os_ << "    Iterator end_token_ = start_token_;\n";
+    os_ << '\n';
+    os_ << "    while (curr_ != end_)\n";
+    os_ << "    {\n";
+
+    if (sm_._seen_BOL_assertion)
+    {
+        os_ << "        const std::size_t BOL_state_ = ptr_[bol_index];\n";
+    }
+
+    if (sm_._seen_EOL_assertion)
+    {
+        os_ << "        const std::size_t EOL_state_ = ptr_[eol_index];\n";
+    }
+
+    if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
+    {
+        os_ << '\n';
+    }
+
+    if (sm_._seen_BOL_assertion && sm_._seen_EOL_assertion)
+    {
+        os_ << "        if (BOL_state_ && (start_token_ == start_ ||\n";
+        os_ << "            *(start_token_ - 1) == '\\n'))\n";
+        os_ << "        {\n";
+        os_ << "            ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+        os_ << "        else if (EOL_state_ && *curr_ == '\\n')\n";
+        os_ << "        {\n";
+        os_ << "            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+        os_ << "        else\n";
+        os_ << "        {\n";
+        os_ << "            const std::size_t state_ =\n";
+
+        if (lookups_ == 256)
+        {
+            os_ << "                ptr_[lookup_[static_cast<unsigned char>\n";
+            os_ << "                (*curr_++)]];\n";
+        }
+        else
+        {
+            os_ << "                ptr_[lookup_[*curr_++]];\n";
+        }
+
+        os_ << '\n';
+        os_ << "            if (state_ == 0) break;\n";
+        os_ << '\n';
+        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+    }
+    else if (sm_._seen_BOL_assertion)
+    {
+        os_ << "        if (BOL_state_ && (start_token_ == start_ ||\n";
+        os_ << "            *(start_token_ - 1) == '\\n'))\n";
+        os_ << "        {\n";
+        os_ << "            ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+        os_ << "        else\n";
+        os_ << "        {\n";
+        os_ << "            const std::size_t state_ =\n";
+
+        if (lookups_ == 256)
+        {
+            os_ << "                ptr_[lookup_[static_cast<unsigned char>\n";
+            os_ << "                (*curr_++)]];\n";
+        }
+        else
+        {
+            os_ << "                ptr_[lookup_[*curr_++]];\n";
+        }
+
+        os_ << '\n';
+        os_ << "            if (state_ == 0) break;\n";
+        os_ << '\n';
+        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+    }
+    else if (sm_._seen_EOL_assertion)
+    {
+        os_ << "        if (EOL_state_ && *curr_ == '\\n')\n";
+        os_ << "        {\n";
+        os_ << "            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+        os_ << "        else\n";
+        os_ << "        {\n";
+        os_ << "            const std::size_t state_ =\n";
+
+        if (lookups_ == 256)
+        {
+            os_ << "                ptr_[lookup_[static_cast<unsigned char>\n";
+            os_ << "                (*curr_++)]];\n";
+        }
+        else
+        {
+            os_ << "                ptr_[lookup_[*curr_++]];\n";
+        }
+
+        os_ << '\n';
+        os_ << "            if (state_ == 0) break;\n";
+        os_ << '\n';
+        os_ << "            ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+        os_ << "        }\n";
+    }
+    else
+    {
+        os_ << "        const std::size_t state_ =\n";
+
+        if (lookups_ == 256)
+        {
+            os_ << "            ptr_[lookup_[static_cast<unsigned char>\n";
+            os_ << "            (*curr_++)]];\n";
+        }
+        else
+        {
+            os_ << "            ptr_[lookup_[*curr_++]];\n";
+        }
+
+        os_ << '\n';
+        os_ << "        if (state_ == 0) break;\n";
+        os_ << '\n';
+        os_ << "        ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
+    }
+
+    os_ << '\n';
+    os_ << "        if (*ptr_)\n";
+    os_ << "        {\n";
+    os_ << "            end_state_ = true;\n";
+    os_ << "            id_ = *(ptr_ + id_index);\n";
+
+    if (dfas_ > 1)
+    {
+        os_ << "            start_state_ = *(ptr_ + state_index);\n";
+    }
+
+    os_ << "            end_token_ = curr_;\n";
+    os_ << "        }\n";
+    os_ << "    }\n";
+    os_ << '\n';
+
+    if (sm_._seen_EOL_assertion)
+    {
+        os_ << "    const std::size_t EOL_state_ = ptr_[eol_index];\n";
+        os_ << '\n';
+        os_ << "    if (EOL_state_ && curr_ == end_)\n";
+        os_ << "    {\n";
+        os_ << "        ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
+        os_ << '\n';
+        os_ << "        if (*ptr_)\n";
+        os_ << "        {\n";
+        os_ << "            end_state_ = true;\n";
+        os_ << "            id_ = *(ptr_ + id_index);\n";
+
+        if (dfas_ > 1)
+        {
+            os_ << "            start_state_ = *(ptr_ + state_index);\n";
+        }
+
+        os_ << "            end_token_ = curr_;\n";
+        os_ << "        }\n";
+        os_ << "    }\n";
+        os_ << '\n';
+    }
+
+    os_ << "    if (end_state_)\n";
+    os_ << "    {\n";
+    os_ << "        // return longest match\n";
+    os_ << "        start_token_ = end_token_;\n";
+
+    if (dfas_ > 1)
+    {
+        os_ << '\n';
+        os_ << "        if (id_ == 0) goto again;\n";
+    }
+
+    os_ << "    }\n";
+    os_ << "    else\n";
+    os_ << "    {\n";
+
+    if (skip_unknown_)
+    {
+        os_ << "        // No match causes char to be skipped\n";
+        os_ << "        ++start_token_;\n";
+    }
+
+    os_ << "        id_ = npos;\n";
+    os_ << "    }\n";
+    os_ << '\n';
+    os_ << "    return id_;\n";
+    os_ << "}\n";
+    os_ << "\n#endif\n";
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/generator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/generator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,817 @@
+// generator.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_GENERATOR_HPP
+#define BOOST_LEXER_GENERATOR_HPP
+
+#include "char_traits.hpp"
+#include "partition/charset.hpp"
+#include "partition/equivset.hpp"
+#include <memory>
+#include "parser/tree/node.hpp"
+#include "parser/parser.hpp"
+#include "containers/ptr_list.hpp"
+#include "rules.hpp"
+#include "state_machine.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+template<typename CharT, typename Traits = char_traits<CharT> >
+class basic_generator
+{
+public:
+    typedef state_machine::size_t_vector size_t_vector;
+    typedef basic_rules<CharT> rules;
+
+    static void build (const rules &rules_, state_machine &state_machine_)
+    {
+        std::size_t index_ = 0;
+        std::size_t size_ = rules_.statemap ().size ();
+        node_ptr_vector node_ptr_vector_;
+
+        state_machine_.clear ();
+
+        for (; index_ < size_; ++index_)
+        {
+            state_machine_._lookup->push_back (0);
+            state_machine_._lookup->back () = new size_t_vector;
+            state_machine_._dfa_alphabet.push_back (0);
+            state_machine_._dfa->push_back (0);
+            state_machine_._dfa->back () = new size_t_vector;
+        }
+
+        for (index_ = 0, size_ = state_machine_._lookup->size ();
+            index_ < size_; ++index_)
+        {
+            state_machine_._lookup[index_]->resize (sizeof (CharT) == 1 ?
+                num_chars : num_wchar_ts, dead_state_index);
+
+            if (!rules_.regexes ()[index_].empty ())
+            {
+                // vector mapping token indexes to partitioned token index sets
+                index_set_vector set_mapping_;
+                // syntax tree
+                internal::node *root_ = build_tree (rules_, index_,
+                    node_ptr_vector_, state_machine_._lookup[index_],
+                    set_mapping_, state_machine_._dfa_alphabet[index_],
+                    state_machine_._seen_BOL_assertion,
+                    state_machine_._seen_EOL_assertion);
+
+                build_dfa (root_, set_mapping_,
+                    state_machine_._dfa_alphabet[index_],
+                    *state_machine_._dfa[index_]);
+            }
+        }
+    }
+
+    static void minimise (state_machine &state_machine_)
+    {
+        const std::size_t machines_ = state_machine_._dfa->size ();
+
+        for (std::size_t i_ = 0; i_ < machines_; ++i_)
+        {
+            const std::size_t dfa_alphabet_ = state_machine_._dfa_alphabet[i_];
+            size_t_vector *dfa_ = state_machine_._dfa[i_];
+
+            if (dfa_alphabet_ != 0)
+            {
+                std::size_t size_ = 0;
+
+                do
+                {
+                    size_ = dfa_->size ();
+                    minimise_dfa (dfa_alphabet_, *dfa_, size_);
+                } while (dfa_->size () != size_);
+            }
+        }
+    }
+
+protected:
+    typedef internal::basic_charset<CharT> charset;
+    typedef internal::ptr_list<charset> charset_list;
+    typedef std::auto_ptr<charset> charset_ptr;
+    typedef internal::equivset equivset;
+    typedef internal::ptr_list<equivset> equivset_list;
+    typedef std::auto_ptr<equivset> equivset_ptr;
+    typedef typename charset::index_set index_set;
+    typedef std::vector<index_set> index_set_vector;
+    typedef internal::basic_parser<CharT> parser;
+    typedef typename parser::node_ptr_vector node_ptr_vector;
+    typedef std::set<const internal::node *> node_set;
+    typedef internal::ptr_vector<node_set> node_set_vector;
+    typedef std::vector<const internal::node *> node_vector;
+    typedef internal::ptr_vector<node_vector> node_vector_vector;
+    typedef typename parser::string string;
+    typedef std::pair<string, string> string_pair;
+    typedef typename parser::tokeniser::string_token string_token;
+    typedef std::deque<string_pair> macro_deque;
+    typedef std::pair<string, const internal::node *> macro_pair;
+    typedef typename parser::macro_map::iterator macro_iter;
+    typedef std::pair<macro_iter, bool> macro_iter_pair;
+    typedef typename parser::tokeniser::token_map token_map;
+
+    static internal::node *build_tree (const rules &rules_,
+        const std::size_t state_, node_ptr_vector &node_ptr_vector_,
+        size_t_vector *lookup_, index_set_vector &set_mapping_,
+        std::size_t &dfa_alphabet_, bool &seen_BOL_assertion_,
+        bool &seen_EOL_assertion_)
+    {
+        const typename rules::string_deque_deque ®exes_ =
+            rules_.regexes ();
+        const typename rules::id_vector_deque &ids_ = rules_.ids ();
+        const typename rules::id_vector_deque &states_ = rules_.states ();
+        typename rules::string_deque::const_iterator regex_iter_ =
+            regexes_[state_].begin ();
+        typename rules::string_deque::const_iterator regex_iter_end_ =
+            regexes_[state_].end ();
+        typename rules::id_vector::const_iterator ids_iter_ =
+            ids_[state_].begin ();
+        typename rules::id_vector::const_iterator states_iter_ =
+            states_[state_].begin ();
+        const typename rules::string ®ex_ = *regex_iter_;
+        // map of regex charset tokens (strings) to index
+        token_map token_map_;
+        const typename rules::string_pair_deque ¯odeque_ =
+            rules_.macrodeque ();
+        typename parser::macro_map macromap_;
+        typename internal::node::node_vector tree_vector_;
+
+        build_macros (token_map_, macrodeque_, macromap_,
+            rules_.case_sensitive (), rules_.locale (), node_ptr_vector_,
+            rules_.dot_not_newline (), seen_BOL_assertion_,
+            seen_EOL_assertion_);
+
+        internal::node *root_ = parser::parse (regex_.c_str (),
+            regex_.c_str () + regex_.size (), *ids_iter_, *states_iter_,
+            rules_.case_sensitive (), rules_.dot_not_newline (),
+            rules_.locale (), node_ptr_vector_, macromap_, token_map_,
+            seen_BOL_assertion_, seen_EOL_assertion_);
+
+        ++regex_iter_;
+        ++ids_iter_;
+        ++states_iter_;
+        tree_vector_.push_back (root_);
+
+        // build syntax trees
+        while (regex_iter_ != regex_iter_end_)
+        {
+            // re-declare var, otherwise we perform an assignment..!
+            const typename rules::string ®ex_ = *regex_iter_;
+
+            root_ = parser::parse (regex_.c_str (),
+                regex_.c_str () + regex_.size (), *ids_iter_,
+                *states_iter_, rules_.case_sensitive (),
+                rules_.dot_not_newline (), rules_.locale (), node_ptr_vector_,
+                macromap_, token_map_, seen_BOL_assertion_,
+                seen_EOL_assertion_);
+            tree_vector_.push_back (root_);
+            ++regex_iter_;
+            ++ids_iter_;
+            ++states_iter_;
+        }
+
+        if (seen_BOL_assertion_)
+        {
+            // Fixup BOLs
+            typename internal::node::node_vector::iterator iter_ =
+                tree_vector_.begin ();
+            typename internal::node::node_vector::iterator end_ =
+                tree_vector_.end ();
+
+            for (; iter_ != end_; ++iter_)
+            {
+                fixup_bol (*iter_, node_ptr_vector_);
+            }
+        }
+
+        // join trees
+        {
+            typename internal::node::node_vector::iterator iter_ =
+                tree_vector_.begin ();
+            typename internal::node::node_vector::iterator end_ =
+                tree_vector_.end ();
+
+            if (iter_ != end_)
+            {
+                root_ = *iter_;
+                ++iter_;
+            }
+
+            for (; iter_ != end_; ++iter_)
+            {
+                node_ptr_vector_->push_back (0);
+                node_ptr_vector_->back () = new internal::selection_node
+                    (root_, *iter_);
+                root_ = node_ptr_vector_->back ();
+            }
+        }
+
+        // partitioned token list
+        charset_list token_list_;
+
+        set_mapping_.resize (token_map_.size ());
+        partition_tokens (token_map_, token_list_);
+
+        typename charset_list::list::const_iterator iter_ =
+            token_list_->begin ();
+        typename charset_list::list::const_iterator end_ =
+            token_list_->end ();
+        std::size_t index_ = 0;
+
+        for (; iter_ != end_; ++iter_, ++index_)
+        {
+            const charset *cs_ = *iter_;
+            typename charset::index_set::const_iterator set_iter_ =
+                cs_->_index_set.begin ();
+            typename charset::index_set::const_iterator set_end_ =
+                cs_->_index_set.end ();
+
+            fill_lookup (cs_->_token, lookup_, index_);
+
+            for (; set_iter_ != set_end_; ++set_iter_)
+            {
+                set_mapping_[*set_iter_].insert (index_);
+            }
+        }
+
+        dfa_alphabet_ = token_list_->size () + dfa_offset;
+        return root_;
+    }
+
+    static void build_macros (token_map &token_map_,
+        const macro_deque ¯odeque_,
+        typename parser::macro_map ¯omap_, const bool case_sensitive_,
+        const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
+        const bool not_dot_newline_, bool &seen_BOL_assertion_,
+        bool &seen_EOL_assertion_)
+    {
+        for (typename macro_deque::const_iterator iter_ =
+            macrodeque_.begin (), end_ = macrodeque_.end ();
+            iter_ != end_; ++iter_)
+        {
+            const typename rules::string &name_ = iter_->first;
+            const typename rules::string ®ex_ = iter_->second;
+            internal::node *node_ = parser::parse (regex_.c_str (),
+                regex_.c_str () + regex_.size (), 0, 0, case_sensitive_,
+                not_dot_newline_, locale_, node_ptr_vector_, macromap_,
+                token_map_, seen_BOL_assertion_, seen_EOL_assertion_);
+            macro_iter_pair map_iter_ = macromap_.
+                insert (macro_pair (name_, 0));
+
+            map_iter_.first->second = node_;
+        }
+    }
+
+    static void build_dfa (internal::node *root_,
+        const index_set_vector &set_mapping_, const std::size_t dfa_alphabet_,
+        size_t_vector &dfa_)
+    {
+        typename internal::node::node_vector *followpos_ =
+            &root_->firstpos ();
+        node_set_vector seen_sets_;
+        node_vector_vector seen_vectors_;
+        size_t_vector hash_vector_;
+
+        // 'jam' state
+        dfa_.resize (dfa_alphabet_, 0);
+        closure (followpos_, seen_sets_, seen_vectors_,
+            hash_vector_, dfa_alphabet_, dfa_);
+
+        std::size_t *ptr_ = 0;
+
+        for (std::size_t index_ = 0; index_ < seen_vectors_->size (); ++index_)
+        {
+            equivset_list equiv_list_;
+
+            build_equiv_list (seen_vectors_[index_], set_mapping_, equiv_list_);
+
+            for (typename equivset_list::list::const_iterator iter_ =
+                equiv_list_->begin (), end_ = equiv_list_->end ();
+                iter_ != end_; ++iter_)
+            {
+                equivset *equivset_ = *iter_;
+                const std::size_t transition_ = closure (&equivset_->_followpos,
+                    seen_sets_, seen_vectors_, hash_vector_, dfa_alphabet_, dfa_);
+
+                if (transition_ != npos)
+                {
+                    ptr_ = &dfa_.front () + ((index_ + 1) * dfa_alphabet_);
+
+                    for (typename internal::equivset::index_vector::const_iterator
+                        equiv_iter_ = equivset_->_index_vector.begin (),
+                        equiv_end_ = equivset_->_index_vector.end ();
+                        equiv_iter_ != equiv_end_; ++equiv_iter_)
+                    {
+                        const std::size_t index_ = *equiv_iter_;
+
+                        if (index_ == bol_token)
+                        {
+                            if (ptr_[eol_index] == 0)
+                            {
+                                ptr_[bol_index] = transition_;
+                            }
+                        }
+                        else if (index_ == eol_token)
+                        {
+                            if (ptr_[bol_index] == 0)
+                            {
+                                ptr_[eol_index] = transition_;
+                            }
+                        }
+                        else
+                        {
+                            ptr_[index_ + dfa_offset] = transition_;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    static std::size_t closure (typename internal::node::node_vector *followpos_,
+        node_set_vector &seen_sets_, node_vector_vector &seen_vectors_,
+        size_t_vector &hash_vector_, const std::size_t size_, size_t_vector &dfa_)
+    {
+        bool end_state_ = false;
+        std::size_t id_ = 0;
+        std::size_t state_ = 0;
+        std::size_t hash_ = 0;
+
+        if (followpos_->empty ()) return npos;
+
+        std::size_t index_ = 0;
+        std::auto_ptr<node_set> set_ptr_ (new node_set);
+        std::auto_ptr<node_vector> vector_ptr_ (new node_vector);
+
+        for (typename internal::node::node_vector::const_iterator iter_ =
+            followpos_->begin (), end_ = followpos_->end ();
+            iter_ != end_; ++iter_)
+        {
+            closure_ex (*iter_, end_state_, id_, state_, followpos_,
+                set_ptr_.get (), vector_ptr_.get (), hash_);
+        }
+
+        bool found_ = false;
+
+        // Stop VC++ 2005 crashing...
+        if (!hash_vector_.empty ())
+        {
+            const std::size_t *hash_iter_ = &hash_vector_.front ();
+            const std::size_t *hash_end_ = hash_iter_ + hash_vector_.size ();
+            node_set **set_iter_ = &seen_sets_->front ();
+
+            for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_)
+            {
+                found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_;
+                ++index_;
+
+                if (found_) break;
+            }
+        }
+
+        if (!found_)
+        {
+            seen_sets_->push_back (0);
+            seen_sets_->back () = set_ptr_.release ();
+            seen_vectors_->push_back (0);
+            seen_vectors_->back () = vector_ptr_.release ();
+            hash_vector_.push_back (hash_);
+            // State 0 is the jam state...
+            index_ = seen_sets_->size ();
+
+            const std::size_t old_size_ = dfa_.size ();
+
+            dfa_.resize (old_size_ + size_, 0);
+
+            if (end_state_)
+            {
+                dfa_[old_size_] |= end_state;
+                dfa_[old_size_ + id_index] = id_;
+                dfa_[old_size_ + state_index] = state_;
+            }
+        }
+
+        return index_;
+    }
+
+    static void closure_ex (internal::node *node_, bool &end_state_,
+        std::size_t &id_, std::size_t &state_,
+        typename internal::node::node_vector * /*followpos_*/, node_set *set_ptr_,
+        node_vector *vector_ptr_, std::size_t &hash_)
+    {
+        const bool temp_end_state_ = node_->end_state ();
+
+        if (temp_end_state_)
+        {
+            if (!end_state_)
+            {
+                end_state_ = true;
+                id_ = node_->id ();
+                state_ = node_->lexer_state ();
+            }
+        }
+
+        if (set_ptr_->insert (node_).second)
+        {
+            vector_ptr_->push_back (node_);
+            hash_ += reinterpret_cast<std::size_t> (node_);
+        }
+    }
+
+    static void partition_tokens (const token_map &map_,
+        charset_list &lhs_)
+    {
+        charset_list rhs_;
+
+        fill_rhs_list (map_, rhs_);
+
+        if (!rhs_->empty ())
+        {
+            typename charset_list::list::iterator iter_;
+            typename charset_list::list::iterator end_;
+            charset_ptr overlap_ (new charset);
+
+            lhs_->push_back (0);
+            lhs_->back () = rhs_->front ();
+            rhs_->pop_front ();
+
+            while (!rhs_->empty ())
+            {
+                charset_ptr r_ (rhs_->front ());
+
+                rhs_->pop_front ();
+                iter_ = lhs_->begin ();
+                end_ = lhs_->end ();
+
+                while (!r_->empty () && iter_ != end_)
+                {
+                    typename charset_list::list::iterator l_iter_ = iter_;
+
+                    (*l_iter_)->intersect (*r_.get (), *overlap_.get ());
+
+                    if (overlap_->empty ())
+                    {
+                        ++iter_;
+                    }
+                    else if ((*l_iter_)->empty ())
+                    {
+                        delete *l_iter_;
+                        *l_iter_ = overlap_.release ();
+
+                        // VC++ 6 Hack:
+                        charset_ptr temp_overlap_ (new charset);
+
+                        overlap_ = temp_overlap_;
+                        ++iter_;
+                    }
+                    else if (r_->empty ())
+                    {
+                        delete r_.release ();
+                        r_ = overlap_;
+
+                        // VC++ 6 Hack:
+                        charset_ptr temp_overlap_ (new charset);
+
+                        overlap_ = temp_overlap_;
+                        break;
+                    }
+                    else
+                    {
+                        iter_ = lhs_->insert (++iter_, 0);
+                        *iter_ = overlap_.release ();
+
+                        // VC++ 6 Hack:
+                        charset_ptr temp_overlap_ (new charset);
+
+                        overlap_ = temp_overlap_;
+                        ++iter_;
+                        end_ = lhs_->end ();
+                    }
+                }
+
+                if (!r_->empty ())
+                {
+                    lhs_->push_back (0);
+                    lhs_->back () = r_.release ();
+                }
+            }
+        }
+    }
+
+    static void fill_rhs_list (const token_map &map_,
+        charset_list &list_)
+    {
+        typename parser::tokeniser::token_map::const_iterator iter_ =
+            map_.begin ();
+        typename parser::tokeniser::token_map::const_iterator end_ =
+            map_.end ();
+
+        for (; iter_ != end_; ++iter_)
+        {
+            list_->push_back (0);
+            list_->back () = new charset (iter_->first, iter_->second);
+        }
+    }
+
+    static void fill_lookup (const string_token &token_,
+        size_t_vector *lookup_, const std::size_t index_)
+    {
+        const CharT *curr_ = token_._charset.c_str ();
+        const CharT *chars_end_ = curr_ + token_._charset.size ();
+        std::size_t *ptr_ = &lookup_->front ();
+        const std::size_t max_ = sizeof (CharT) == 1 ?
+            num_chars : num_wchar_ts;
+
+        if (token_._negated)
+        {
+            CharT curr_char_ = sizeof(CharT) == 1 ? -128 : 0;
+            std::size_t i_ = 0;
+
+            while (curr_ < chars_end_)
+            {
+                while (*curr_ > curr_char_)
+                {
+                    ptr_[static_cast<typename Traits::index_type>
+                        (curr_char_)] = index_ + dfa_offset;
+                    ++curr_char_;
+                    ++i_;
+                }
+
+                ++curr_char_;
+                ++curr_;
+                ++i_;
+            }
+
+            for (; i_ < max_; ++i_)
+            {
+                ptr_[static_cast<typename Traits::index_type>(curr_char_)] =
+                    index_ + dfa_offset;
+                ++curr_char_;
+            }
+        }
+        else
+        {
+            while (curr_ < chars_end_)
+            {
+                ptr_[static_cast<typename Traits::index_type>(*curr_)] =
+                    index_ + dfa_offset;
+                ++curr_;
+            }
+        }
+    }
+
+    static void build_equiv_list (const node_vector *vector_,
+        const index_set_vector &set_mapping_, equivset_list &lhs_)
+    {
+        equivset_list rhs_;
+
+        fill_rhs_list (vector_, set_mapping_, rhs_);
+
+        if (!rhs_->empty ())
+        {
+            typename equivset_list::list::iterator iter_;
+            typename equivset_list::list::iterator end_;
+            equivset_ptr overlap_ (new equivset);
+
+            lhs_->push_back (0);
+            lhs_->back () = rhs_->front ();
+            rhs_->pop_front ();
+
+            while (!rhs_->empty ())
+            {
+                equivset_ptr r_ (rhs_->front ());
+
+                rhs_->pop_front ();
+                iter_ = lhs_->begin ();
+                end_ = lhs_->end ();
+
+                while (!r_->empty () && iter_ != end_)
+                {
+                    typename equivset_list::list::iterator l_iter_ = iter_;
+
+                    (*l_iter_)->intersect (*r_.get (), *overlap_.get ());
+
+                    if (overlap_->empty ())
+                    {
+                        ++iter_;
+                    }
+                    else if ((*l_iter_)->empty ())
+                    {
+                        delete *l_iter_;
+                        *l_iter_ = overlap_.release ();
+
+                        // VC++ 6 Hack:
+                        equivset_ptr temp_overlap_ (new equivset);
+
+                        overlap_ = temp_overlap_;
+                        ++iter_;
+                    }
+                    else if (r_->empty ())
+                    {
+                        delete r_.release ();
+                        r_ = overlap_;
+
+                        // VC++ 6 Hack:
+                        equivset_ptr temp_overlap_ (new equivset);
+
+                        overlap_ = temp_overlap_;
+                        break;
+                    }
+                    else
+                    {
+                        iter_ = lhs_->insert (++iter_, 0);
+                        *iter_ = overlap_.release ();
+
+                        // VC++ 6 Hack:
+                        equivset_ptr temp_overlap_ (new equivset);
+
+                        overlap_ = temp_overlap_;
+                        ++iter_;
+                        end_ = lhs_->end ();
+                    }
+                }
+
+                if (!r_->empty ())
+                {
+                    lhs_->push_back (0);
+                    lhs_->back () = r_.release ();
+                }
+            }
+        }
+    }
+
+    static void fill_rhs_list (const node_vector *vector_,
+        const index_set_vector &set_mapping_, equivset_list &list_)
+    {
+        typename node_vector::const_iterator iter_ =
+            vector_->begin ();
+        typename node_vector::const_iterator end_ =
+            vector_->end ();
+
+        for (; iter_ != end_; ++iter_)
+        {
+            const internal::node *node_ = *iter_;
+
+            if (!node_->end_state ())
+            {
+                std::size_t token_ = node_->token ();
+
+                if (token_ != null_token)
+                {
+                    list_->push_back (0);
+
+                    if (token_ == bol_token || token_ == eol_token)
+                    {
+                        std::set<std::size_t> index_set_;
+
+                        index_set_.insert (token_);
+                        list_->back () = new equivset (index_set_,
+                            node_->followpos ());
+                    }
+                    else
+                    {
+                        list_->back () = new equivset (set_mapping_[token_],
+                            node_->followpos ());
+                    }
+                }
+            }
+        }
+    }
+
+    static void fixup_bol (internal::node * &root_,
+        node_ptr_vector &node_ptr_vector_)
+    {
+        typename internal::node::node_vector *first_ = &root_->firstpos ();
+        bool found_ = false;
+        typename internal::node::node_vector::const_iterator iter_ =
+            first_->begin ();
+        typename internal::node::node_vector::const_iterator end_ =
+            first_->end ();
+
+        for (; iter_ != end_; ++iter_)
+        {
+            const internal::node *node_ = *iter_;
+
+            found_ = !node_->end_state () && node_->token () == bol_token;
+
+            if (found_) break;
+        }
+
+        if (!found_)
+        {
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new internal::leaf_node (bol_token);
+
+            internal::node *lhs_ = node_ptr_vector_->back ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new internal::leaf_node (null_token);
+
+            internal::node *rhs_ = node_ptr_vector_->back ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () =
+                new internal::selection_node (lhs_, rhs_);
+            lhs_ = node_ptr_vector_->back ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () =
+                new internal::sequence_node (lhs_, root_);
+            root_ = node_ptr_vector_->back ();
+        }
+    }
+
+    static void minimise_dfa (const std::size_t dfa_alphabet_,
+        size_t_vector &dfa_, std::size_t size_)
+    {
+        const std::size_t *first_ = &dfa_.front ();
+        const std::size_t *second_ = 0;
+        const std::size_t *end_ = first_ + size_;
+        std::size_t index_ = 1;
+        std::size_t new_index_ = 1;
+        std::size_t curr_index_ = 0;
+        index_set index_set_;
+        size_t_vector lookup_;
+        std::size_t *lookup_ptr_ = 0;
+
+        lookup_.resize (size_ / dfa_alphabet_, null_token);
+        lookup_ptr_ = &lookup_.front ();
+        *lookup_ptr_ = 0;
+        // Only one 'jam' state, so skip it.
+        first_ += dfa_alphabet_;
+
+        for (; first_ < end_; first_ += dfa_alphabet_, ++index_)
+        {
+            for (second_ = first_ + dfa_alphabet_, curr_index_ = index_ + 1;
+                second_ < end_; second_ += dfa_alphabet_, ++curr_index_)
+            {
+                if (index_set_.find (curr_index_) != index_set_.end ())
+                {
+                    continue;
+                }
+
+                if (::memcmp (first_, second_, sizeof(std::size_t) *
+                    dfa_alphabet_) == 0)
+                {
+                    index_set_.insert (curr_index_);
+                    lookup_ptr_[curr_index_] = new_index_;
+                }
+            }
+
+            if (lookup_ptr_[index_] == null_token)
+            {
+                lookup_ptr_[index_] = new_index_;
+                ++new_index_;
+            }
+        }
+
+        if (!index_set_.empty ())
+        {
+            const std::size_t *front_ = &dfa_.front ();
+            size_t_vector new_dfa_ (front_, front_ + dfa_alphabet_);
+            typename index_set::iterator set_end_ =
+                index_set_.end ();
+            const std::size_t *ptr_ = front_ + dfa_alphabet_;
+            std::size_t *new_ptr_ = 0;
+
+            new_dfa_.resize (size_ - index_set_.size () * dfa_alphabet_, 0);
+            new_ptr_ = &new_dfa_.front () + dfa_alphabet_;
+            size_ /= dfa_alphabet_;
+
+            for (index_ = 1; index_ < size_; ++index_)
+            {
+                if (index_set_.find (index_) != set_end_)
+                {
+                    ptr_ += dfa_alphabet_;
+                    continue;
+                }
+
+                new_ptr_[end_state_index] = ptr_[end_state_index];
+                new_ptr_[id_index] = ptr_[id_index];
+                new_ptr_[state_index] = ptr_[state_index];
+                new_ptr_[bol_index] = lookup_ptr_[ptr_[bol_index]];
+                new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]];
+                new_ptr_ += dfa_offset;
+                ptr_ += dfa_offset;
+
+                for (std::size_t i_ = dfa_offset; i_ < dfa_alphabet_; ++i_)
+                {
+                    *new_ptr_++ = lookup_ptr_[*ptr_++];
+                }
+            }
+
+            dfa_.swap (new_dfa_);
+        }
+    }
+};
+
+typedef basic_generator<char> generator;
+typedef basic_generator<wchar_t> wgenerator;
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/parser.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/parser.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,503 @@
+// parser.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_PARSER_HPP
+#define BOOST_LEXER_PARSER_HPP
+
+#include <assert.h>
+#include "tree/end_node.hpp"
+#include "tree/iteration_node.hpp"
+#include "tree/leaf_node.hpp"
+#include "../runtime_error.hpp"
+#include "tree/selection_node.hpp"
+#include "tree/sequence_node.hpp"
+#include "../size_t.hpp"
+#include "tokeniser/re_tokeniser.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT>
+class basic_parser
+{
+public:
+    typedef basic_re_tokeniser<CharT> tokeniser;
+    typedef typename tokeniser::string string;
+    typedef std::map<string, const node *> macro_map;
+    typedef node::node_ptr_vector node_ptr_vector;
+    typedef typename tokeniser::num_token token;
+
+/*
+    General principles of regex parsing:
+    - Every regex is a sequence of sub-regexes.
+    - Regexes consist of operands and operators
+    - All operators decompose to sequence, selection ('|') and iteration ('*')
+    - Regex tokens are stored on the stack.
+    - When a complete sequence of regex tokens is on the stack it is processed.
+
+Grammar:
+
+<REGEX>      -> <OREXP>
+<OREXP>      -> <SEQUENCE> | <OREXP>'|'<SEQUENCE>
+<SEQUENCE>   -> <SUB>
+<SUB>        -> <EXPRESSION> | <SUB><EXPRESSION>
+<EXPRESSION> -> <REPEAT>
+<REPEAT>     -> charset | macro | '('<REGEX>')' | <REPEAT><DUPLICATE>
+<DUPLICATE>  -> '?' | '*' | '+' | '{n[,[m]]}'
+*/
+    static node *parse (const CharT *start_, const CharT * const end_,
+        const std::size_t id_, const std::size_t dfa_state_,
+        const bool case_sensitive_, const bool dot_not_newline_,
+        const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
+        const macro_map ¯omap_, typename tokeniser::token_map &map_,
+        bool &seen_BOL_assertion_, bool &seen_EOL_assertion_)
+    {
+        node *root_ = 0;
+        state state_ (start_, end_, case_sensitive_, locale_,
+            dot_not_newline_);
+        token lhs_token_;
+        token rhs_token_;
+        token_stack token_stack_;
+        tree_node_stack tree_node_stack_;
+        char action_ = 0;
+
+        token_stack_.push (rhs_token_);
+        tokeniser::next (state_, map_, rhs_token_);
+
+        do
+        {
+            lhs_token_ = token_stack_.top ();
+            action_ = lhs_token_.precedence (rhs_token_._type);
+
+            switch (action_)
+            {
+            case '<':
+            case '=':
+                token_stack_.push (rhs_token_);
+                tokeniser::next (state_, map_, rhs_token_);
+                break;
+            case '>':
+                reduce (token_stack_, macromap_, node_ptr_vector_,
+                    tree_node_stack_);
+                break;
+            default:
+                std::ostringstream ss_;
+
+                ss_ << "A syntax error occurred: '" <<
+                    lhs_token_.precedence_string () <<
+                    "' against '" << rhs_token_.precedence_string () <<
+                    "' at index " << state_._index << ".";
+                throw runtime_error (ss_.str ().c_str ());
+                break;
+            }
+        } while (!token_stack_.empty ());
+
+        if (tree_node_stack_.empty ())
+        {
+            throw runtime_error ("Empty rules are not allowed.");
+        }
+
+        assert (tree_node_stack_.size () == 1);
+
+        node *lhs_node_  = tree_node_stack_.top ();
+
+        tree_node_stack_.pop ();
+
+        if (id_ == 0)
+        {
+            // Macros have no end state...
+            root_ = lhs_node_;
+        }
+        else
+        {
+            node_ptr_vector_->push_back (0);
+
+            node *rhs_node_ = new end_node (id_, dfa_state_);
+
+            node_ptr_vector_->back () = rhs_node_;
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new sequence_node (lhs_node_, rhs_node_);
+            root_ = node_ptr_vector_->back ();
+        }
+
+        // Done this way as bug in VC++ 6 prevents |= operator working
+        // properly!
+        if (state_._seen_BOL_assertion) seen_BOL_assertion_ = true;
+
+        if (state_._seen_EOL_assertion) seen_EOL_assertion_ = true;
+
+        return root_;
+    }
+
+private:
+    typedef typename tokeniser::state state;
+    typedef std::stack<token> token_stack;
+    typedef node::node_stack tree_node_stack;
+
+    static void reduce (token_stack &token_stack_,
+        const macro_map ¯omap_, node_ptr_vector &node_vector_ptr_,
+        tree_node_stack &tree_node_stack_)
+    {
+        typename tokeniser::num_token lhs_;
+        typename tokeniser::num_token rhs_;
+        token_stack handle_;
+        char action_ = 0;
+
+        do
+        {
+            rhs_ = token_stack_.top ();
+            token_stack_.pop ();
+            handle_.push (rhs_);
+
+            if (!token_stack_.empty ())
+            {
+                lhs_ = token_stack_.top ();
+                action_ = lhs_.precedence (rhs_._type);
+            }
+        } while (!token_stack_.empty () && action_ == '=');
+
+        assert (token_stack_.empty () || action_ == '<');
+
+        switch (rhs_._type)
+        {
+        case token::BEGIN:
+            // finished processing so exit
+            break;
+        case token::REGEX:
+            // finished parsing, nothing to do
+            break;
+        case token::OREXP:
+            orexp (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
+            break;
+        case token::SEQUENCE:
+            token_stack_.push (token::OREXP);
+            break;
+        case token::SUB:
+            sub (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
+            break;
+        case token::EXPRESSION:
+            token_stack_.push (token::SUB);
+            break;
+        case token::REPEAT:
+            repeat (handle_, token_stack_);
+            break;
+        case token::CHARSET:
+            charset (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
+            break;
+        case token::MACRO:
+            macro (handle_, token_stack_, macromap_, node_vector_ptr_, tree_node_stack_);
+            break;
+        case token::OPENPAREN:
+            openparen (handle_, token_stack_);
+            break;
+        case token::OPT:
+            optional (node_vector_ptr_, tree_node_stack_);
+            token_stack_.push (token::DUP);
+            break;
+        case token::ZEROORMORE:
+            zero_or_more (node_vector_ptr_, tree_node_stack_);
+            token_stack_.push (token::DUP);
+            break;
+        case token::ONEORMORE:
+            one_or_more (node_vector_ptr_, tree_node_stack_);
+            token_stack_.push (token::DUP);
+            break;
+        case token::REPEATN:
+            repeatn (handle_.top (), node_vector_ptr_, tree_node_stack_);
+            token_stack_.push (token::DUP);
+            break;
+        default:
+            throw runtime_error
+                ("Internal error regex_parser::reduce");
+            break;
+        }
+    }
+
+    static void orexp (token_stack &handle_, token_stack &token_stack_,
+        node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
+    {
+        assert (handle_.top ()._type == token::OREXP &&
+            (handle_.size () == 1 || handle_.size () == 3));
+
+        if (handle_.size () == 1)
+        {
+            token_stack_.push (token::REGEX);
+        }
+        else
+        {
+            handle_.pop ();
+            assert (handle_.top ()._type == token::OR);
+            handle_.pop ();
+            assert (handle_.top ()._type == token::SEQUENCE);
+            perform_or (node_ptr_vector_, tree_node_stack_);
+            token_stack_.push (token::OREXP);
+        }
+    }
+
+    static void sub (token_stack &handle_, token_stack &token_stack_,
+        node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
+    {
+        assert (handle_.top ()._type == token::SUB &&
+            handle_.size () == 1 || handle_.size () == 2);
+
+        if (handle_.size () == 1)
+        {
+            token_stack_.push (token::SEQUENCE);
+        }
+        else
+        {
+            handle_.pop ();
+            assert (handle_.top ()._type == token::EXPRESSION);
+            // perform join
+            sequence (node_ptr_vector_, tree_node_stack_);
+            token_stack_.push (token::SUB);
+        }
+    }
+
+    static void repeat (token_stack &handle_, token_stack &token_stack_)
+    {
+        assert (handle_.top ()._type == token::REPEAT &&
+            handle_.size () >= 1 && handle_.size () <= 3);
+
+        if (handle_.size () == 1)
+        {
+            token_stack_.push (token::EXPRESSION);
+        }
+        else
+        {
+            handle_.pop ();
+            assert (handle_.top ()._type == token::DUP);
+            token_stack_.push (token::REPEAT);
+        }
+    }
+
+    static void charset (token_stack &handle_, token_stack &token_stack_,
+        node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
+    {
+        assert (handle_.top ()._type == token::CHARSET &&
+            handle_.size () == 1);
+        // store charset
+        node_ptr_vector_->push_back (0);
+
+        const size_t id_ = handle_.top ()._id;
+
+        node_ptr_vector_->back () = new leaf_node (id_);
+        tree_node_stack_.push (node_ptr_vector_->back ());
+        token_stack_.push (token::REPEAT);
+    }
+
+    static void macro (token_stack &handle_, token_stack &token_stack_,
+        const macro_map ¯omap_, node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        token &top_ = handle_.top ();
+
+        assert (top_._type == token::MACRO && handle_.size () == 1);
+
+        typename macro_map::const_iterator iter_ =
+            macromap_.find (top_._macro);
+
+        if (iter_ == macromap_.end ())
+        {
+            const CharT *name_ = top_._macro;
+            std::basic_stringstream<CharT> ss_;
+            std::ostringstream os_;
+
+            os_ << "Unknown MACRO name '";
+
+            while (*name_)
+            {
+                os_ << ss_.narrow (*name_++, ' ');
+            }
+
+            os_ << "'.";
+            throw runtime_error (os_.str ());
+        }
+
+        tree_node_stack_.push (iter_->second->copy (node_ptr_vector_));
+        token_stack_.push (token::REPEAT);
+    }
+
+    static void openparen (token_stack &handle_, token_stack &token_stack_)
+    {
+        assert (handle_.top ()._type == token::OPENPAREN &&
+            handle_.size () == 3);
+        handle_.pop ();
+        assert (handle_.top ()._type == token::REGEX);
+        handle_.pop ();
+        assert (handle_.top ()._type == token::CLOSEPAREN);
+        token_stack_.push (token::REPEAT);
+    }
+
+    static void perform_or (node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        // perform or
+        node *rhs_ = tree_node_stack_.top ();
+
+        tree_node_stack_.pop ();
+
+        node *lhs_ = tree_node_stack_.top ();
+
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
+        tree_node_stack_.top () = node_ptr_vector_->back ();
+    }
+
+    static void sequence (node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        node *rhs_  = tree_node_stack_.top ();
+
+        tree_node_stack_.pop ();
+
+        node *lhs_ = tree_node_stack_.top ();
+
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
+        tree_node_stack_.top () = node_ptr_vector_->back ();
+    }
+
+    static void optional (node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        // perform ?
+        node *lhs_ = tree_node_stack_.top ();
+
+        node_ptr_vector_->push_back (0);
+
+        node *rhs_  = new leaf_node (null_token);
+
+        node_ptr_vector_->back () = rhs_;
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
+        tree_node_stack_.top () = node_ptr_vector_->back ();
+    }
+
+    static void zero_or_more (node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        // perform *
+        node *ptr_ = tree_node_stack_.top ();
+
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new iteration_node (ptr_);
+        tree_node_stack_.top () = node_ptr_vector_->back ();
+    }
+
+    static void one_or_more (node_ptr_vector &node_ptr_vector_,
+        tree_node_stack &tree_node_stack_)
+    {
+        // perform +
+        node *lhs_  = tree_node_stack_.top ();
+        node *copy_ = lhs_->copy (node_ptr_vector_);
+
+        node_ptr_vector_->push_back (0);
+
+        node *rhs_ = new iteration_node (copy_);
+
+        node_ptr_vector_->back () = rhs_;
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
+        tree_node_stack_.top () = node_ptr_vector_->back ();
+    }
+
+    static void repeatn (const token &token_,
+        node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
+    {
+        // perform {n[,[m]]}
+        // Semantic checks have already been performed.
+        // {0,}  = *
+        // {0,1} = ?
+        // {1,}  = +
+        // therefore we do not check for these cases.
+        if (!(token_._min == 1 && !token_._comma))
+        {
+            const std::size_t top_ = token_._min > 0 ?
+                token_._min : token_._max;
+
+            if (token_._min == 0)
+            {
+                optional (node_ptr_vector_, tree_node_stack_);
+            }
+
+            node *prev_ = tree_node_stack_.top ()->copy (node_ptr_vector_);
+            node *curr_ = 0;
+
+            for (std::size_t i_ = 2; i_ < top_; ++i_)
+            {
+                node *temp_  = prev_->copy (node_ptr_vector_);
+
+                curr_ = temp_;
+                tree_node_stack_.push (0);
+                tree_node_stack_.top () = prev_;
+                sequence (node_ptr_vector_, tree_node_stack_);
+                prev_ = curr_;
+            }
+
+            if (token_._comma && token_._min > 0)
+            {
+                if (token_._min > 1)
+                {
+                    node *temp_  = prev_->copy (node_ptr_vector_);
+
+                    curr_ = temp_;
+                    tree_node_stack_.push (0);
+                    tree_node_stack_.top () = prev_;
+                    sequence (node_ptr_vector_, tree_node_stack_);
+                    prev_ = curr_;
+                }
+
+                if (token_._comma && token_._max)
+                {
+                    tree_node_stack_.push (0);
+                    tree_node_stack_.top () = prev_;
+                    optional (node_ptr_vector_, tree_node_stack_);
+
+                    node *temp_  = tree_node_stack_.top ();
+
+                    tree_node_stack_.pop ();
+                    prev_ = temp_;
+
+                    const std::size_t count_ = token_._max - token_._min;
+
+                    for (std::size_t i_ = 1; i_ < count_; ++i_)
+                    {
+                        node *temp_ = prev_->copy (node_ptr_vector_);
+
+                        curr_ = temp_;
+                        tree_node_stack_.push (0);
+                        tree_node_stack_.top () = prev_;
+                        sequence (node_ptr_vector_, tree_node_stack_);
+                        prev_ = curr_;
+                    }
+                }
+                else
+                {
+                    tree_node_stack_.push (0);
+                    tree_node_stack_.top () = prev_;
+                    zero_or_more (node_ptr_vector_, tree_node_stack_);
+
+                    node *temp_  = tree_node_stack_.top ();
+
+                    prev_ = temp_;
+                    tree_node_stack_.pop ();
+                }
+            }
+
+            tree_node_stack_.push (0);
+            tree_node_stack_.top () = prev_;
+            sequence (node_ptr_vector_, tree_node_stack_);
+        }
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,132 @@
+// num_token.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_NUM_TOKEN_HPP
+#define BOOST_LEXER_NUM_TOKEN_HPP
+
+#include "../../consts.hpp" // null_token
+#include "../../size_t.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT>
+struct basic_num_token
+{
+    enum type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT,
+        DUP, OR, CHARSET, MACRO, OPENPAREN, CLOSEPAREN, OPT,
+        ZEROORMORE, ONEORMORE, REPEATN, END};
+
+    type _type;
+    std::size_t _id;
+    std::size_t _min;
+    bool _comma;
+    std::size_t _max;
+    CharT _macro[max_macro_len + 1];
+    static const char _precedence_table[END + 1][END + 1];
+    static const char *_precedence_strings[END + 1];
+
+    basic_num_token (const type type_ = BEGIN,
+        const std::size_t id_ = null_token) :
+        _type (type_),
+        _id (id_),
+        _min (0),
+        _comma (false),
+        _max (0)
+    {
+        *_macro = 0;
+    }
+
+    basic_num_token &operator = (const basic_num_token &rhs_)
+    {
+        _type = rhs_._type;
+        _id = rhs_._id;
+        _min = rhs_._min;
+        _comma = rhs_._comma;
+        _max = rhs_._max;
+
+        if (_type == MACRO)
+        {
+            const CharT *read_ = rhs_._macro;
+            CharT *write_ = _macro;
+
+            while (*read_)
+            {
+                *write_++ = *read_++;
+            }
+
+            *write_ = 0;
+        }
+
+        return *this;
+    }
+
+    void set (const type type_)
+    {
+        _type = type_;
+        _id = null_token;
+    }
+
+    void set (const type type_, const std::size_t id_)
+    {
+        _type = type_;
+        _id = id_;
+    }
+
+    void min_max (const std::size_t min_, const bool comma_,
+        const std::size_t max_)
+    {
+        _min = min_;
+        _comma = comma_;
+        _max = max_;
+    }
+
+    char precedence (const type type_) const
+    {
+        return _precedence_table[_type][type_];
+    }
+
+    const char *precedence_string () const
+    {
+        return _precedence_strings[_type];
+    }
+};
+
+template<typename CharT>
+const char basic_num_token<CharT>::_precedence_table[END + 1][END + 1] = {
+//        BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP,  | , CHR, MCR,  ( ,  ) ,  ? ,  * ,  + , {n}, END
+/*BEGIN*/{' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', '>'},
+/*REGEX*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', '>'},
+/*OREXP*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', '>'},
+/* SEQ */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', '>'},
+/* SUB */{' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '>', ' ', ' ', ' ', ' ', '>'},
+/*EXPRE*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/* RPT */{' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '<', '<', '<', '<', '>'},
+/*DUPLI*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/*  |  */{' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' '},
+/*CHARA*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
+/*MACRO*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
+/*  (  */{' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' '},
+/*  )  */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
+/*  ?  */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/*  *  */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/*  +  */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/*{n,m}*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', '>'},
+/* END */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
+};
+
+template<typename CharT>
+const char *basic_num_token<CharT>::_precedence_strings[END + 1] =
+{"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", "REPEAT",
+    "DUPLICATE", "|", "CHARSET", "MACRO", "(", ")", "?", "*", "+",
+    "{n[,[m]]}", "END"};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,432 @@
+// tokeniser.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_RE_TOKENISER_HPP
+#define BOOST_LEXER_RE_TOKENISER_HPP
+
+#include <map>
+#include "num_token.hpp"
+#include "../../runtime_error.hpp"
+#include "../../size_t.hpp"
+#include <sstream>
+#include "../../string_token.hpp"
+#include "re_tokeniser_helper.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT>
+class basic_re_tokeniser
+{
+public:
+    typedef basic_num_token<CharT> num_token;
+    typedef basic_re_tokeniser_state<CharT> state;
+    typedef basic_string_token<CharT> string_token;
+    typedef typename string_token::string string;
+    typedef std::map<string_token, std::size_t> token_map;
+    typedef std::pair<string_token, std::size_t> token_pair;
+
+    static void next (state &state_, token_map &map_, num_token &token_)
+    {
+        CharT ch_ = 0;
+        bool eos_ = state_.next (ch_);
+
+        token_.min_max (0, false, 0);
+
+        while (!eos_ && ch_ == '"')
+        {
+            state_._in_string ^= 1;
+            eos_ = state_.next (ch_);
+        }
+
+        if (eos_)
+        {
+            if (state_._in_string)
+            {
+                throw runtime_error ("Unexpected end of regex "
+                    "(missing '\"').");
+            }
+
+            token_.set (num_token::END, null_token);
+        }
+        else
+        {
+            if (ch_ == '\\')
+            {
+                // Even if we are in a string, respect escape sequences...
+                escape (state_, map_, token_);
+            }
+            else if (state_._in_string)
+            {
+                // All other meta characters lose their special meaning
+                // inside a string.
+                create_charset_token (string (1, ch_), false, map_, token_);
+            }
+            else
+            {
+                // Not an escape sequence and not inside a string, so
+                // check for meta characters.
+                switch (ch_)
+                {
+                case '(':
+                    token_.set (num_token::OPENPAREN, null_token);
+                    ++state_._paren_count;
+                    break;
+                case ')':
+                    --state_._paren_count;
+
+                    if (state_._paren_count < 0)
+                    {
+                        std::ostringstream ss_;
+
+                        ss_ << "Number of open parenthesis < 0 at index " <<
+                            state_._index - 1 << '.';
+                        throw runtime_error (ss_.str ().c_str ());
+                    }
+
+                    token_.set (num_token::CLOSEPAREN, null_token);
+                    break;
+                case '?':
+                    token_.set (num_token::OPT, null_token);
+                    break;
+                case '*':
+                    token_.set (num_token::ZEROORMORE, null_token);
+                    break;
+                case '+':
+                    token_.set (num_token::ONEORMORE, null_token);
+                    break;
+                case '{':
+                    open_curly (state_, token_);
+                    break;
+                case '|':
+                    token_.set (num_token::OR, null_token);
+                    break;
+                case '^':
+                    token_.set (num_token::CHARSET, bol_token);
+                    state_._seen_BOL_assertion = true;
+                    break;
+                case '$':
+                    token_.set (num_token::CHARSET, eol_token);
+                    state_._seen_EOL_assertion = true;
+                    break;
+                case '.':
+                {
+                    string dot_;
+
+                    if (state_._dot_not_newline)
+                    {
+                        dot_ = '\n';
+                    }
+
+                    create_charset_token (dot_, true, map_, token_);
+                    break;
+                }
+                case '[':
+                {
+                    charset (state_, map_, token_);
+                    break;
+                }
+                default:
+                    if (!state_._case_sensitive &&
+                        (std::isupper (ch_, state_._locale) ||
+                        std::islower (ch_, state_._locale)))
+                    {
+                        CharT upper_ = std::toupper (ch_, state_._locale);
+                        CharT lower_ = std::tolower (ch_, state_._locale);
+
+                        string str_ (1, upper_);
+
+                        str_ += lower_;
+                        create_charset_token (str_, false, map_, token_);
+                    }
+                    else
+                    {
+                        create_charset_token (string (1, ch_), false,
+                            map_, token_);
+                    }
+
+                    break;
+                }
+            }
+        }
+    }
+
+private:
+    typedef basic_re_tokeniser_helper<CharT> tokeniser_helper;
+
+    static void escape (state &state_, token_map &map_, num_token &token_)
+    {
+        CharT ch_ = 0;
+        std::size_t str_len_ = 0;
+        const CharT *str_ = tokeniser_helper::escape_sequence (state_,
+            ch_, str_len_);
+
+        if (str_)
+        {
+            state state2_ (str_ + 1, str_ + str_len_, state_._case_sensitive,
+                state_._locale, state_._dot_not_newline);
+
+            charset (state2_, map_, token_);
+        }
+        else
+        {
+            create_charset_token (string (1, ch_), false, map_, token_);
+        }
+    }
+
+    static void charset (state &state_, token_map &map_, num_token &token_)
+    {
+        string chars_;
+        bool negated_ = false;
+
+        tokeniser_helper::charset (state_, chars_, negated_);
+        create_charset_token (chars_, negated_, map_, token_);
+    }
+
+    static void create_charset_token (const string &charset_,
+        const bool negated_, token_map &map_, num_token &token_)
+    {
+        std::size_t id_ = null_token;
+        string_token stok_ (negated_, charset_);
+
+        stok_.remove_duplicates ();
+        stok_.normalise ();
+
+        typename token_map::const_iterator iter_ = map_.find (stok_);
+
+        if (iter_ == map_.end ())
+        {
+            id_ = map_.size ();
+            map_.insert (token_pair (stok_, id_));
+        }
+        else
+        {
+            id_ = iter_->second;
+        }
+
+        token_.set (num_token::CHARSET, id_);
+    }
+
+    static void open_curly (state &state_, num_token &token_)
+    {
+        if (state_.eos ())
+        {
+            throw runtime_error ("Unexpected end of regex "
+                "(missing '}').");
+        }
+        else if (*state_._curr >= '0' && *state_._curr <= '9')
+        {
+            repeat_n (state_, token_);
+        }
+        else
+        {
+            macro (state_, token_);
+        }
+    }
+
+    // SYNTAX:
+    //   {n[,[n]]}
+    // SEMANTIC RULES:
+    //   {0} - INVALID (throw exception)
+    //   {0,} = *
+    //   {0,0} - INVALID (throw exception)
+    //   {0,1} = ?
+    //   {1,} = +
+    //   {min,max} where min == max - {min}
+    //   {min,max} where max < min - INVALID (throw exception)
+    static void repeat_n (state &state_, num_token &token_)
+    {
+        CharT ch_ = 0;
+        bool eos_ = state_.next (ch_);
+
+        while (!eos_ && ch_ >= '0' && ch_ <= '9')
+        {
+            token_._min *= 10;
+            token_._min += ch_ - '0';
+            eos_ = state_.next (ch_);
+        }
+
+        if (eos_)
+        {
+            throw runtime_error ("Unexpected end of regex "
+                "(missing '}').");
+        }
+
+        bool min_max_ = false;
+        bool repeatn_ = true;
+
+        token_._comma = ch_ == ',';
+
+        if (token_._comma)
+        {
+            eos_ = state_.next (ch_);
+
+            if (eos_)
+            {
+                throw runtime_error ("Unexpected end of regex "
+                    "(missing '}').");
+            }
+
+            if (ch_ == '}')
+            {
+                // Small optimisation: Check for '*' equivalency.
+                if (token_._min == 0)
+                {
+                    token_.set (num_token::ZEROORMORE, null_token);
+                    repeatn_ = false;
+                }
+                // Small optimisation: Check for '+' equivalency.
+                else if (token_._min == 1)
+                {
+                    token_.set (num_token::ONEORMORE, null_token);
+                    repeatn_ = false;
+                }
+            }
+            else
+            {
+                if (ch_ < '0' || ch_ > '9')
+                {
+                    std::ostringstream ss_;
+
+                    ss_ << "Missing '}' at index " << state_._index - 1 << '.';
+                    throw runtime_error (ss_.str ().c_str ());
+                }
+
+                min_max_ = true;
+
+                do
+                {
+                    token_._max *= 10;
+                    token_._max += ch_ - '0';
+                    eos_ = state_.next (ch_);
+                } while (!eos_ && ch_ >= '0' && ch_ <= '9');
+
+                if (eos_)
+                {
+                    throw runtime_error ("Unexpected end of regex "
+                        "(missing '}').");
+                }
+
+                // Small optimisation: Check for '?' equivalency.
+                if (token_._min == 0 && token_._max == 1)
+                {
+                    token_.set (num_token::OPT, null_token);
+                    repeatn_ = false;
+                }
+                // Small optimisation: if min == max, then min.
+                else if (token_._min == token_._max)
+                {
+                    token_._comma = false;
+                    min_max_ = false;
+                    token_._max = 0;
+                }
+            }
+        }
+
+        if (ch_ != '}')
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Missing '}' at index " << state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        if (repeatn_)
+        {
+            // SEMANTIC VALIDATION follows:
+            // NOTE: {0,} has already become *
+            // therefore we don't check for a comma.
+            if (token_._min == 0 && token_._max == 0)
+            {
+                std::ostringstream ss_;
+
+                ss_ << "Cannot have exactly zero repeats preceding index " <<
+                    state_._index << '.';
+                throw runtime_error (ss_.str ().c_str ());
+            }
+
+            if (min_max_ && token_._max < token_._min)
+            {
+                std::ostringstream ss_;
+
+                ss_ << "Max less than min preceding index " << state_._index
+                    << '.';
+                throw runtime_error (ss_.str ().c_str ());
+            }
+
+            token_.set (num_token::REPEATN, null_token);
+        }
+    }
+
+    static void macro (state &state_, num_token &token_)
+    {
+        CharT ch_ = 0;
+        bool eos_ = false;
+        const CharT *start_ = state_._curr;
+
+        state_.next (ch_);
+
+        if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') &&
+            !(ch_ >= 'a' && ch_ <= 'z'))
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Invalid MACRO name at index " <<
+                state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        do
+        {
+            eos_ = state_.next (ch_);
+
+            if (eos_)
+            {
+                throw runtime_error ("Unexpected end of regex "
+                    "(missing '}').");
+            }
+        } while (ch_ == '_' || ch_ == '-' || ch_ >= 'A' && ch_ <= 'Z' ||
+            ch_ >= 'a' && ch_ <= 'z' || ch_ >= '0' && ch_ <= '9');
+
+        if (ch_ != '}')
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Missing '}' at index " << state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        std::size_t len_ = state_._curr - 1 - start_;
+
+        if (len_ > max_macro_len)
+        {
+            std::basic_stringstream<CharT> ss_;
+            std::ostringstream os_;
+
+            os_ << "MACRO name '";
+
+            while (len_)
+            {
+                os_ << ss_.narrow (*start_++, ' ');
+                --len_;
+            }
+
+            os_ << "' too long.";
+            throw runtime_error (os_.str ());
+        }
+
+        token_.set (num_token::MACRO, null_token);
+        ::memcpy (token_._macro, start_, len_ * sizeof(CharT));
+        token_._macro[len_] = 0;
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_helper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_helper.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,546 @@
+// tokeniser_helper.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_RE_TOKENISER_HELPER_H
+#define BOOST_LEXER_RE_TOKENISER_HELPER_H
+
+#include "../../char_traits.hpp"
+#include "../../size_t.hpp"
+#include "re_tokeniser_state.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT, typename Traits = char_traits<CharT> >
+class basic_re_tokeniser_helper
+{
+public:
+    typedef basic_re_tokeniser_state<CharT> state;
+    typedef std::basic_string<CharT> string;
+
+    static const CharT *escape_sequence (state &state_, CharT &ch_,
+        std::size_t &str_len_)
+    {
+        bool eos_ = state_.eos ();
+
+        if (eos_)
+        {
+            throw runtime_error ("Unexpected end of regex "
+                "following '\\'.");
+        }
+
+        const CharT *str_ = charset_shortcut (*state_._curr, str_len_);
+
+        if (str_)
+        {
+            state_.increment ();
+        }
+        else
+        {
+            ch_ = chr (state_);
+        }
+
+        return str_;
+    }
+
+    // This function can call itself.
+    static void charset (state &state_, string &chars_, bool &negated_)
+    {
+        CharT ch_ = 0;
+        bool eos_ = state_.next (ch_);
+
+        if (eos_)
+        {
+            // Pointless returning index if at end of string
+            throw runtime_error ("Unexpected end of regex "
+                "following '['.");
+        }
+
+        negated_ = ch_ == '^';
+
+        if (negated_)
+        {
+            eos_ = state_.next (ch_);
+
+            if (eos_)
+            {
+                // Pointless returning index if at end of string
+                throw runtime_error ("Unexpected end of regex "
+                    "following '^'.");
+            }
+        }
+
+        bool chset_ = false;
+        CharT prev_ = 0;
+
+        while (ch_ != ']')
+        {
+            if (ch_ == '\\')
+            {
+                std::size_t str_len_ = 0;
+                const CharT *str_ = escape_sequence (state_, prev_, str_len_);
+
+                chset_ = str_ != 0;
+
+                if (chset_)
+                {
+                    state temp_state_ (str_ + 1, str_ + str_len_,
+                        state_._case_sensitive, state_._locale,
+                        state_._dot_not_newline);
+                    string temp_chars_;
+                    bool temp_negated_ = false;
+
+                    charset (temp_state_, temp_chars_, temp_negated_);
+
+                    if (negated_ != temp_negated_)
+                    {
+                        std::ostringstream ss_;
+
+                        ss_ << "Mismatch in charset negation preceding "
+                            "index " << state_._index - 1 << '.';
+                        throw runtime_error (ss_.str ().c_str ());
+                    }
+
+                    chars_ += temp_chars_;
+                }
+            }
+/*
+            else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
+            {
+                // TODO: POSIX charsets
+            }
+*/
+            else
+            {
+                chset_ = false;
+                prev_ = ch_;
+            }
+
+            eos_ = state_.next (ch_);
+
+            // Covers preceding if, else if and else
+            if (eos_)
+            {
+                // Pointless returning index if at end of string
+                throw runtime_error ("Unexpected end of regex "
+                    "(missing ']').");
+            }
+
+            if (ch_ == '-')
+            {
+                charset_range (chset_, state_, eos_, ch_, prev_, chars_);
+            }
+            else if (!chset_)
+            {
+                if (!state_._case_sensitive &&
+                    (std::isupper (prev_, state_._locale) ||
+                    std::islower (prev_, state_._locale)))
+                {
+                    CharT upper_ = std::toupper (prev_, state_._locale);
+                    CharT lower_ = std::tolower (prev_, state_._locale);
+
+                    chars_ += upper_;
+                    chars_ += lower_;
+                }
+                else
+                {
+                    chars_ += prev_;
+                }
+            }
+        }
+
+        if (!negated_ && chars_.empty ())
+        {
+            throw runtime_error ("Empty charsets not allowed.");
+        }
+    }
+
+private:
+    static const char *charset_shortcut (const char ch_,
+        std::size_t &str_len_)
+    {
+        const char *str_ = 0;
+
+        switch (ch_)
+        {
+        case 'd':
+            str_ = "[0-9]";
+            break;
+        case 'D':
+            str_ = "[^0-9]";
+            break;
+        case 's':
+            str_ = "[ \t\n\r\f\v]";
+            break;
+        case 'S':
+            str_ = "[^ \t\n\r\f\v]";
+            break;
+        case 'w':
+            str_ = "[_0-9A-Za-z]";
+            break;
+        case 'W':
+            str_ = "[^_0-9A-Za-z]";
+            break;
+        }
+
+        if (str_)
+        {
+            str_len_ = strlen (str_);
+        }
+        else
+        {
+            str_len_ = 0;
+        }
+
+        return str_;
+    }
+
+    static const wchar_t *charset_shortcut (const wchar_t ch_,
+        std::size_t &str_len_)
+    {
+        const wchar_t *str_ = 0;
+
+        switch (ch_)
+        {
+        case 'd':
+            str_ = L"[0-9]";
+            break;
+        case 'D':
+            str_ = L"[^0-9]";
+            break;
+        case 's':
+            str_ = L"[ \t\n\r\f\v]";
+            break;
+        case 'S':
+            str_ = L"[^ \t\n\r\f\v]";
+            break;
+        case 'w':
+            str_ = L"[_0-9A-Za-z]";
+            break;
+        case 'W':
+            str_ = L"[^_0-9A-Za-z]";
+            break;
+        }
+
+        if (str_)
+        {
+            str_len_ = wcslen (str_);
+        }
+        else
+        {
+            str_len_ = 0;
+        }
+
+        return str_;
+    }
+
+    static CharT chr (state &state_)
+    {
+        CharT ch_ = 0;
+
+        // eos_ has already been checked for.
+        switch (*state_._curr)
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+                ch_ = decode_octal (state_);
+                break;
+            case 'a':
+                ch_ = '\a';
+                state_.increment ();
+                break;
+            case 'b':
+                ch_ = '\b';
+                state_.increment ();
+                break;
+            case 'c':
+                ch_ = decode_control_char (state_);
+                break;
+            case 'e':
+                ch_ = 27; // '\e' not recognised by compiler
+                state_.increment ();
+                break;
+            case 'f':
+                ch_ = '\f';
+                state_.increment ();
+                break;
+            case 'n':
+                ch_ = '\n';
+                state_.increment ();
+                break;
+            case 'r':
+                ch_ = '\r';
+                state_.increment ();
+                break;
+            case 't':
+                ch_ = '\t';
+                state_.increment ();
+                break;
+            case 'v':
+                ch_ = '\v';
+                state_.increment ();
+                break;
+            case 'x':
+                ch_ = decode_hex (state_);
+                break;
+            default:
+                ch_ = *state_._curr;
+                state_.increment ();
+                break;
+        }
+
+        return ch_;
+    }
+
+    static CharT decode_octal (state &state_)
+    {
+        std::size_t accumulator_ = 0;
+        CharT ch_ = 0;
+        unsigned short count_ = 3;
+        bool eos_ = state_.next (ch_);
+
+        do
+        {
+            accumulator_ *= 8;
+            accumulator_ += ch_ - '0';
+            --count_;
+            eos_ = state_.eos ();
+
+            if (!eos_)
+            {
+                ch_ = *state_._curr;
+
+                // Don't consume invalid chars!
+                if (ch_ >= '0' && ch_ <= '7')
+                {
+                    state_.increment ();
+                }
+                else
+                {
+                    eos_ = true;
+                }
+            }
+        } while (!eos_ && count_);
+
+        return static_cast<CharT> (accumulator_);
+    }
+
+    static CharT decode_control_char (state &state_)
+    {
+        // Skip over 'c'
+        state_.increment ();
+
+        CharT ch_ = 0;
+        bool eos_ = state_.next (ch_);
+
+        if (eos_)
+        {
+            // Pointless returning index if at end of string
+            throw runtime_error ("Unexpected end of regex following \\c.");
+        }
+        else
+        {
+            if (ch_ >= 'a' && ch_ <= 'z')
+            {
+                ch_ -= 'a' - 1;
+            }
+            else if (ch_ >= 'A' && ch_ <= 'Z')
+            {
+                ch_ -= 'A' - 1;
+            }
+            else if (ch_ == '@')
+            {
+                // Apparently...
+                ch_ = 0;
+            }
+            else
+            {
+                std::ostringstream ss_;
+
+                ss_ << "Invalid control char at index " <<
+                    state_._index - 1 << '.';
+                throw runtime_error (ss_.str ().c_str ());
+            }
+        }
+
+        return ch_;
+    }
+
+    static CharT decode_hex (state &state_)
+    {
+        // Skip over 'x'
+        state_.increment ();
+
+        CharT ch_ = 0;
+        bool eos_ = state_.next (ch_);
+
+        if (eos_)
+        {
+            // Pointless returning index if at end of string
+            throw runtime_error ("Unexpected end of regex following \\x.");
+        }
+
+        if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') ||
+            (ch_ >= 'A' && ch_ <= 'F')))
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Illegal char following \\x at index " <<
+                state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        std::size_t hex_ = 0;
+
+        do
+        {
+            hex_ *= 16;
+
+            if (ch_ >= '0' && ch_ <= '9')
+            {
+                hex_ += ch_ - '0';
+            }
+            else if (ch_ >= 'a' && ch_ <= 'f')
+            {
+                hex_ += 10 + (ch_ - 'a');
+            }
+            else
+            {
+                hex_ += 10 + (ch_ - 'A');
+            }
+
+            eos_ = state_.eos ();
+
+            if (!eos_)
+            {
+                ch_ = *state_._curr;
+
+                // Don't consume invalid chars!
+                if (((ch_ >= '0' && ch_ <= '9') ||
+                    (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F')))
+                {
+                    state_.increment ();
+                }
+                else
+                {
+                    eos_ = true;
+                }
+            }
+        } while (!eos_);
+
+        return static_cast<CharT> (hex_);
+    }
+
+    static void charset_range (const bool chset_, state &state_, bool &eos_,
+        CharT &ch_, const CharT prev_, string &chars_)
+    {
+        if (chset_)
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Charset cannot form start of range preceding "
+                "index " << state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        eos_ = state_.next (ch_);
+
+        if (eos_)
+        {
+            // Pointless returning index if at end of string
+            throw runtime_error ("Unexpected end of regex "
+                "following '-'.");
+        }
+
+        CharT curr_ = 0;
+
+        if (ch_ == '\\')
+        {
+            std::size_t str_len_ = 0;
+
+            if (escape_sequence (state_, curr_, str_len_))
+            {
+                std::ostringstream ss_;
+
+                ss_ << "Charset cannot form end of range preceding index "
+                    << state_._index << '.';
+                throw runtime_error (ss_.str ().c_str ());
+            }
+        }
+/*
+        else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
+        {
+            std::ostringstream ss_;
+
+            ss_ << "POSIX char class cannot form end of range at "
+                "index " << state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+*/
+        else
+        {
+            curr_ = ch_;
+        }
+
+        eos_ = state_.next (ch_);
+
+        // Covers preceding if and else
+        if (eos_)
+        {
+            // Pointless returning index if at end of string
+            throw runtime_error ("Unexpected end of regex "
+                "(missing ']').");
+        }
+
+        std::size_t start_ = static_cast<typename Traits::index_type> (prev_);
+        std::size_t end_ = static_cast<typename Traits::index_type> (curr_);
+
+        // Semanic check
+        if (end_ < start_)
+        {
+            std::ostringstream ss_;
+
+            ss_ << "Invalid range in charset preceding index " <<
+                state_._index - 1 << '.';
+            throw runtime_error (ss_.str ().c_str ());
+        }
+
+        chars_.reserve (chars_.size () + (end_ + 1 - start_));
+
+        for (; start_ <= end_; ++start_)
+        {
+            CharT ch_ = static_cast<CharT> (start_);
+
+            if (!state_._case_sensitive &&
+                (std::isupper (ch_, state_._locale) ||
+                std::islower (ch_, state_._locale)))
+            {
+                CharT upper_ = std::toupper (ch_, state_._locale);
+                CharT lower_ = std::tolower (ch_, state_._locale);
+
+                chars_ += (upper_);
+                chars_ += (lower_);
+            }
+            else
+            {
+                chars_ += (ch_);
+            }
+        }
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_state.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser_state.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,94 @@
+// tokeniser_state.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_RE_TOKENISER_STATE_HPP
+#define BOOST_LEXER_RE_TOKENISER_STATE_HPP
+
+#include <locale>
+#include "../../size_t.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT>
+struct basic_re_tokeniser_state
+{
+    const CharT *_curr;
+    const CharT * const _end;
+    bool _case_sensitive;
+    std::locale _locale;
+    bool _dot_not_newline;
+    std::size_t _index;
+    long _paren_count;
+    bool _in_string;
+    bool _seen_BOL_assertion;
+    bool _seen_EOL_assertion;
+
+    basic_re_tokeniser_state (const CharT *regex_, const CharT * const end_,
+        const bool case_sensitive_, const std::locale locale_,
+        const bool dot_not_newline_) :
+        _curr (regex_),
+        _end (end_),
+        _case_sensitive (case_sensitive_),
+        _locale (locale_),
+        _dot_not_newline (dot_not_newline_),
+        _index (0),
+        _paren_count (0),
+        _in_string (false),
+        _seen_BOL_assertion (false),
+        _seen_EOL_assertion (false)
+    {
+    }
+
+    // prevent VC++ 7.1 warning:
+    const basic_re_tokeniser_state &operator = (const basic_re_tokeniser_state &rhs_)
+    {
+        _curr = rhs_._curr;
+        _end = rhs_._end;
+        _case_sensitive = rhs_._case_sensitive;
+        _locale = rhs_._locale;
+        _dot_not_newline = rhs_._dot_not_newline;
+        _index = rhs_._index;
+        _paren_count = rhs_._paren_count;
+        _in_string = rhs_._in_string;
+        _seen_BOL_assertion = rhs_._seen_BOL_assertion;
+        _seen_EOL_assertion = rhs_._seen_EOL_assertion;
+        return this;
+    }
+
+    inline bool next (CharT &ch_)
+    {
+        if (_curr >= _end)
+        {
+            ch_ = 0;
+            return true;
+        }
+        else
+        {
+            ch_ = *_curr;
+            increment ();
+            return false;
+        }
+    }
+
+    inline void increment ()
+    {
+        ++_curr;
+        ++_index;
+    }
+
+    inline bool eos ()
+    {
+        return _curr >= _end;
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/end_node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/end_node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,82 @@
+// end_node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_END_NODE_HPP
+#define BOOST_LEXER_END_NODE_HPP
+
+#include "node.hpp"
+#include "../../size_t.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class end_node : public node
+{
+public:
+    end_node (const std::size_t id_, const std::size_t lexer_state_) :
+        node (false),
+        _id (id_),
+        _lexer_state (lexer_state_)
+    {
+        node::_firstpos.push_back (this);
+        node::_lastpos.push_back (this);
+    }
+
+    virtual ~end_node ()
+    {
+    }
+
+    virtual type what_type () const
+    {
+        return END;
+    }
+
+    virtual bool traverse (const_node_stack &/*node_stack_*/,
+        bool_stack &/*perform_op_stack_*/) const
+    {
+        return false;
+    }
+
+    virtual const node_vector &followpos () const
+    {
+        // _followpos is always empty..!
+        return _followpos;
+    }
+
+    virtual bool end_state () const
+    {
+        return true;
+    }
+
+    virtual std::size_t id () const
+    {
+        return _id;
+    }
+
+    virtual std::size_t lexer_state () const
+    {
+        return _lexer_state;
+    }
+
+private:
+    std::size_t _id;
+    std::size_t _lexer_state;
+    node_vector _followpos;
+
+    virtual void copy_node (node_ptr_vector &/*node_ptr_vector_*/,
+        node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/,
+        bool &/*down_*/) const
+    {
+        // Nothing to do, as end_nodes are not copied.
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/iteration_node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/iteration_node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,82 @@
+// iteration_node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_ITERATION_NODE_HPP
+#define BOOST_LEXER_ITERATION_NODE_HPP
+
+#include "node.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class iteration_node : public node
+{
+public:
+    iteration_node (node *next_) :
+        node (true),
+        _next (next_)
+    {
+        node_vector::iterator iter_;
+        node_vector::iterator end_;
+
+        _next->append_firstpos (_firstpos);
+        _next->append_lastpos (_lastpos);
+
+        for (iter_ = _lastpos.begin (), end_ = _lastpos.end ();
+            iter_ != end_; ++iter_)
+        {
+            (*iter_)->append_followpos (_firstpos);
+        }
+    }
+
+    virtual ~iteration_node ()
+    {
+    }
+
+    virtual type what_type () const
+    {
+        return ITERATION;
+    }
+
+    virtual bool traverse (const_node_stack &node_stack_,
+        bool_stack &perform_op_stack_) const
+    {
+        perform_op_stack_.push (true);
+        node_stack_.push (_next);
+        return true;
+    }
+
+private:
+    // Not owner of this pointer...
+    node *_next;
+
+    virtual void copy_node (node_ptr_vector &node_ptr_vector_,
+        node_stack &new_node_stack_, bool_stack &perform_op_stack_,
+        bool &down_) const
+    {
+        if (perform_op_stack_.top ())
+        {
+            node *ptr_  = new_node_stack_.top ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new iteration_node (ptr_);
+            new_node_stack_.top () = node_ptr_vector_->back ();
+        }
+        else
+        {
+            down_ = true;
+        }
+
+        perform_op_stack_.pop ();
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/leaf_node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/leaf_node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,89 @@
+// leaf_node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_LEAF_NODE_HPP
+#define BOOST_LEXER_LEAF_NODE_HPP
+
+#include "../../consts.hpp" // null_token
+#include "node.hpp"
+#include "../../size_t.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class leaf_node : public node
+{
+public:
+    leaf_node (const std::size_t token_) :
+        node (token_ == null_token),
+        _token (token_)
+    {
+        if (!_nullable)
+        {
+            _firstpos.push_back (this);
+            _lastpos.push_back (this);
+        }
+    }
+
+    virtual ~leaf_node ()
+    {
+    }
+
+    virtual void append_followpos (const node_vector &followpos_)
+    {
+        for (node_vector::const_iterator iter_ = followpos_.begin (),
+            end_ = followpos_.end (); iter_ != end_; ++iter_)
+        {
+            _followpos.push_back (*iter_);
+        }
+    }
+
+    virtual type what_type () const
+    {
+        return LEAF;
+    }
+
+    virtual bool traverse (const_node_stack &/*node_stack_*/,
+        bool_stack &/*perform_op_stack_*/) const
+    {
+        return false;
+    }
+
+    virtual std::size_t token () const
+    {
+        return _token;
+    }
+
+    virtual const node_vector &followpos () const
+    {
+        return _followpos;
+    }
+
+    virtual node_vector &followpos ()
+    {
+        return _followpos;
+    }
+
+private:
+    std::size_t _token;
+    node_vector _followpos;
+
+    virtual void copy_node (node_ptr_vector &node_ptr_vector_,
+        node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/,
+        bool &/*down_*/) const
+    {
+        node_ptr_vector_->push_back (0);
+        node_ptr_vector_->back () = new leaf_node (_token);
+        new_node_stack_.push (node_ptr_vector_->back ());
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,172 @@
+// node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_NODE_HPP
+#define BOOST_LEXER_NODE_HPP
+
+#include <assert.h>
+#include "../../containers/ptr_vector.hpp"
+#include "../../runtime_error.hpp"
+#include "../../size_t.hpp"
+#include <stack>
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class node
+{
+public:
+    enum type {LEAF, SEQUENCE, SELECTION, ITERATION, END};
+
+    typedef std::stack<bool> bool_stack;
+    typedef std::stack<node *> node_stack;
+    // stack and vector not owner of node pointers
+    typedef std::stack<const node *> const_node_stack;
+    typedef std::vector<node *> node_vector;
+    typedef ptr_vector<node> node_ptr_vector;
+
+    node () :
+        _nullable (false)
+    {
+    }
+
+    node (const bool nullable_) :
+        _nullable (nullable_)
+    {
+    }
+
+    virtual ~node ()
+    {
+    }
+
+    bool nullable () const
+    {
+        return _nullable;
+    }
+
+    void append_firstpos (node_vector &firstpos_) const
+    {
+        firstpos_.insert (firstpos_.end (),
+            _firstpos.begin (), _firstpos.end ());
+    }
+
+    void append_lastpos (node_vector &lastpos_) const
+    {
+        lastpos_.insert (lastpos_.end (),
+            _lastpos.begin (), _lastpos.end ());
+    }
+
+    virtual void append_followpos (const node_vector &/*followpos_*/)
+    {
+        throw runtime_error ("Internal error node::append_followpos");
+    }
+
+    node *copy (node_ptr_vector &node_ptr_vector_) const
+    {
+        node *new_root_ = 0;
+        const_node_stack node_stack_;
+        bool_stack perform_op_stack_;
+        bool down_ = true;
+        node_stack new_node_stack_;
+
+        node_stack_.push (this);
+
+        while (!node_stack_.empty ())
+        {
+            while (down_)
+            {
+                down_ = node_stack_.top ()->traverse (node_stack_,
+                    perform_op_stack_);
+            }
+
+            while (!down_ && !node_stack_.empty ())
+            {
+                const node *top_ = node_stack_.top ();
+
+                top_->copy_node (node_ptr_vector_, new_node_stack_, perform_op_stack_, down_);
+
+                if (!down_) node_stack_.pop ();
+            }
+        }
+
+        assert (new_node_stack_.size () == 1);
+        new_root_ = new_node_stack_.top ();
+        new_node_stack_.pop ();
+        return new_root_;
+    }
+
+    virtual type what_type () const = 0;
+
+    virtual bool traverse (const_node_stack &node_stack_,
+        bool_stack &perform_op_stack_) const = 0;
+
+    node_vector &firstpos ()
+    {
+        return _firstpos;
+    }
+
+    const node_vector &firstpos () const
+    {
+        return _firstpos;
+    }
+
+    // _lastpos modified externally, so not const &
+    node_vector &lastpos ()
+    {
+        return _lastpos;
+    }
+
+    virtual bool end_state () const
+    {
+        return false;
+    }
+
+    virtual std::size_t id () const
+    {
+        throw runtime_error ("Internal error node::id");
+    }
+
+    virtual std::size_t lexer_state () const
+    {
+        throw runtime_error ("Internal error node::state");
+    }
+
+    virtual std::size_t token () const
+    {
+        throw runtime_error ("Internal error node::token");
+    }
+
+    virtual const node_vector &followpos () const
+    {
+        throw runtime_error ("Internal error node::followpos");
+    }
+
+    virtual node_vector &followpos ()
+    {
+        throw runtime_error ("Internal error node::followpos");
+    }
+
+protected:
+    const bool _nullable;
+    node_vector _firstpos;
+    node_vector _lastpos;
+
+    virtual void copy_node (node_ptr_vector &node_ptr_vector_,
+        node_stack &new_node_stack_, bool_stack &perform_op_stack_,
+        bool &down_) const = 0;
+
+private:
+    node (node const &); // No copy construction.
+    node &operator = (node const &); // No assignment.
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/selection_node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/selection_node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,94 @@
+// selection_node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_SELECTION_NODE_HPP
+#define BOOST_LEXER_SELECTION_NODE_HPP
+
+#include "node.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class selection_node : public node
+{
+public:
+    selection_node (node *left_, node *right_) :
+        node (left_->nullable () || right_->nullable ()),
+        _left (left_),
+        _right (right_)
+    {
+        _left->append_firstpos (_firstpos);
+        _right->append_firstpos (_firstpos);
+        _left->append_lastpos (_lastpos);
+        _right->append_lastpos (_lastpos);
+    }
+
+    virtual ~selection_node ()
+    {
+    }
+
+    virtual type what_type () const
+    {
+        return SELECTION;
+    }
+
+    virtual bool traverse (const_node_stack &node_stack_,
+        bool_stack &perform_op_stack_) const
+    {
+        perform_op_stack_.push (true);
+
+        switch (_right->what_type ())
+        {
+        case SEQUENCE:
+        case SELECTION:
+        case ITERATION:
+            perform_op_stack_.push (false);
+            break;
+        default:
+            break;
+        }
+
+        node_stack_.push (_right);
+        node_stack_.push (_left);
+        return true;
+    }
+
+private:
+    // Not owner of these pointers...
+    node *_left;
+    node *_right;
+
+    virtual void copy_node (node_ptr_vector &node_ptr_vector_,
+        node_stack &new_node_stack_, bool_stack &perform_op_stack_,
+        bool &down_) const
+    {
+        if (perform_op_stack_.top ())
+        {
+            node *rhs_  = new_node_stack_.top ();
+
+            new_node_stack_.pop ();
+
+            node *lhs_ = new_node_stack_.top ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
+            new_node_stack_.top () = node_ptr_vector_->back ();
+        }
+        else
+        {
+            down_ = true;
+        }
+
+        perform_op_stack_.pop ();
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/parser/tree/sequence_node.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/parser/tree/sequence_node.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,112 @@
+// sequence_node.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_SEQUENCE_NODE_HPP
+#define BOOST_LEXER_SEQUENCE_NODE_HPP
+
+#include "node.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+class sequence_node : public node
+{
+public:
+    sequence_node (node *left_, node *right_) :
+        node (left_->nullable () && right_->nullable ()),
+        _left (left_),
+        _right (right_)
+    {
+        _left->append_firstpos (_firstpos);
+
+        if (_left->nullable ())
+        {
+            _right->append_firstpos (_firstpos);
+        }
+
+        if (_right->nullable ())
+        {
+            _left->append_lastpos (_lastpos);
+        }
+
+        _right->append_lastpos (_lastpos);
+
+        node_vector &lastpos_ = _left->lastpos ();
+        const node_vector &firstpos_ = _right->firstpos ();
+
+        for (node_vector::iterator iter_ = lastpos_.begin (),
+            end_ = lastpos_.end (); iter_ != end_; ++iter_)
+        {
+            (*iter_)->append_followpos (firstpos_);
+        }
+    }
+
+    virtual ~sequence_node ()
+    {
+    }
+
+    virtual type what_type () const
+    {
+        return SEQUENCE;
+    }
+
+    virtual bool traverse (const_node_stack &node_stack_,
+        bool_stack &perform_op_stack_) const
+    {
+        perform_op_stack_.push (true);
+
+        switch (_right->what_type ())
+        {
+        case SEQUENCE:
+        case SELECTION:
+        case ITERATION:
+            perform_op_stack_.push (false);
+            break;
+        default:
+            break;
+        }
+
+        node_stack_.push (_right);
+        node_stack_.push (_left);
+        return true;
+    }
+
+private:
+    // Not owner of these pointers...
+    node *_left;
+    node *_right;
+
+    virtual void copy_node (node_ptr_vector &node_ptr_vector_,
+        node_stack &new_node_stack_, bool_stack &perform_op_stack_,
+        bool &down_) const
+    {
+        if (perform_op_stack_.top ())
+        {
+            node *rhs_ = new_node_stack_.top ();
+
+            new_node_stack_.pop ();
+
+            node *lhs_ = new_node_stack_.top ();
+
+            node_ptr_vector_->push_back (0);
+            node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
+            new_node_stack_.top () = node_ptr_vector_->back ();
+        }
+        else
+        {
+            down_ = true;
+        }
+
+        perform_op_stack_.pop ();
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/partition/charset.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/partition/charset.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,81 @@
+// charset.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_CHARSET_HPP
+#define BOOST_LEXER_CHARSET_HPP
+
+#include <set>
+#include "../size_t.hpp"
+#include "../string_token.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+template<typename CharT>
+struct basic_charset
+{
+    typedef basic_string_token<CharT> token;
+    typedef std::set<std::size_t> index_set;
+
+    token _token;
+    index_set _index_set;
+
+    basic_charset ()
+    {
+    }
+
+    basic_charset (const token &token_, const std::size_t index_) :
+        _token (token_)
+    {
+        _index_set.insert (index_);
+    }
+
+    bool empty () const
+    {
+        return _token.empty () && _index_set.empty ();
+    }
+
+    void intersect (basic_charset &rhs_, basic_charset &overlap_)
+    {
+        _token.intersect (rhs_._token, overlap_._token);
+
+        if (!overlap_._token.empty ())
+        {
+            typename index_set::const_iterator iter_ = _index_set.begin ();
+            typename index_set::const_iterator end_ = _index_set.end ();
+
+            for (; iter_ != end_; ++iter_)
+            {
+                overlap_._index_set.insert (*iter_);
+            }
+
+            iter_ = rhs_._index_set.begin ();
+            end_ = rhs_._index_set.end ();
+
+            for (; iter_ != end_; ++iter_)
+            {
+                overlap_._index_set.insert (*iter_);
+            }
+
+            if (_token.empty ())
+            {
+                _index_set.clear ();
+            }
+
+            if (rhs_._token.empty ())
+            {
+                rhs_._index_set.clear ();
+            }
+        }
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/partition/equivset.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/partition/equivset.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,130 @@
+// equivset.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_EQUIVSET_HPP
+#define BOOST_LEXER_EQUIVSET_HPP
+
+#include <algorithm>
+#include "../parser/tree/node.hpp"
+#include <set>
+#include "../size_t.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+namespace internal
+{
+struct equivset
+{
+    typedef std::set<std::size_t> index_set;
+    typedef std::vector<std::size_t> index_vector;
+    // Not owner of nodes:
+    typedef std::vector<node *> node_vector;
+
+    index_vector _index_vector;
+    node_vector _followpos;
+
+    equivset ()
+    {
+    }
+
+    equivset (const index_set &index_set_,
+        const node_vector &followpos_) :
+        _followpos (followpos_)
+    {
+        index_set::const_iterator iter_ = index_set_.begin ();
+        index_set::const_iterator end_ = index_set_.end ();
+
+        for (; iter_ != end_; ++iter_)
+        {
+            _index_vector.push_back (*iter_);
+        }
+    }
+
+    bool empty () const
+    {
+        return _index_vector.empty () && _followpos.empty ();
+    }
+
+    void intersect (equivset &rhs_, equivset &overlap_)
+    {
+        intersect_indexes (rhs_._index_vector, overlap_._index_vector);
+
+        if (!overlap_._index_vector.empty ())
+        {
+            overlap_._followpos = _followpos;
+
+            node_vector::const_iterator overlap_begin_ =
+                overlap_._followpos.begin ();
+            node_vector::const_iterator overlap_end_ =
+                overlap_._followpos.end ();
+            node_vector::const_iterator rhs_iter_ =
+                rhs_._followpos.begin ();
+            node_vector::const_iterator rhs_end_ =
+                rhs_._followpos.end ();
+
+            for (; rhs_iter_ != rhs_end_; ++rhs_iter_)
+            {
+                node *node_ = *rhs_iter_;
+
+                if (std::find (overlap_begin_, overlap_end_, node_) ==
+                    overlap_end_)
+                {
+                    overlap_._followpos.push_back (node_);
+                    overlap_begin_ = overlap_._followpos.begin ();
+                    overlap_end_ = overlap_._followpos.end ();
+                }
+            }
+
+            if (_index_vector.empty ())
+            {
+                _followpos.clear ();
+            }
+
+            if (rhs_._index_vector.empty ())
+            {
+                rhs_._followpos.clear ();
+            }
+        }
+    }
+
+private:
+    void intersect_indexes (index_vector &rhs_, index_vector &overlap_)
+    {
+        index_vector::iterator iter_ = _index_vector.begin ();
+        index_vector::iterator end_ = _index_vector.end ();
+        index_vector::iterator rhs_iter_ = rhs_.begin ();
+        index_vector::iterator rhs_end_ = rhs_.end ();
+
+        while (iter_ != end_ && rhs_iter_ != rhs_end_)
+        {
+            const std::size_t index_ = *iter_;
+            const std::size_t rhs_index_ = *rhs_iter_;
+
+            if (index_ < rhs_index_)
+            {
+                ++iter_;
+            }
+            else if (index_ > rhs_index_)
+            {
+                ++rhs_iter_;
+            }
+            else
+            {
+                overlap_.push_back (index_);
+                iter_ = _index_vector.erase (iter_);
+                end_ = _index_vector.end ();
+                rhs_iter_ = rhs_.erase (rhs_iter_);
+                rhs_end_ = rhs_.end ();
+            }
+        }
+    }
+};
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/rules.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/rules.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,531 @@
+// rules.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_RULES_HPP
+#define BOOST_LEXER_RULES_HPP
+
+#include "consts.hpp"
+#include <deque>
+#include <locale>
+#include <map>
+#include "runtime_error.hpp"
+#include <set>
+#include "size_t.hpp"
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace boost
+{
+namespace lexer
+{
+
+namespace detail
+{
+    // return name of initial state
+    template <typename CharT>
+    struct initial;
+
+    template <>
+    struct initial<char>
+    {
+        static char const* call() { return "INITIAL"; }
+    };
+
+    template <>
+    struct initial<wchar_t>
+    {
+        static wchar_t const* call() { return L"INITIAL"; }
+    };
+}
+
+template<typename CharT>
+class basic_rules
+{
+public:
+    typedef std::vector<std::size_t> id_vector;
+    typedef std::deque<id_vector> id_vector_deque;
+    typedef std::basic_string<CharT> string;
+    typedef std::deque<string> string_deque;
+    typedef std::deque<string_deque> string_deque_deque;
+    typedef std::set<string> string_set;
+    typedef std::pair<string, string> string_pair;
+    typedef std::deque<string_pair> string_pair_deque;
+    typedef std::map<string, std::size_t> string_size_t_map;
+    typedef std::pair<string, std::size_t> string_size_t_pair;
+
+    basic_rules (const bool case_sensitive_ = true,
+        const bool dot_not_newline_ = false) :
+        _case_sensitive (case_sensitive_),
+        _dot_not_newline (dot_not_newline_)
+    {
+        add_state (detail::initial<CharT>::call());
+    }
+
+    void clear ()
+    {
+        _statemap.clear ();
+        _macrodeque.clear ();
+        _macroset.clear ();
+        _regexes.clear ();
+        _ids.clear ();
+        _states.clear ();
+        _case_sensitive = true;
+        _locale = std::locale ();
+        _dot_not_newline = false;
+
+        add_state (detail::initial<CharT>::call());
+    }
+
+    void clear (const CharT *state_name_)
+    {
+        std::size_t state_ = state (state_name_);
+
+        if (state_ != npos)
+        {
+            _regexes[state_].clear ();
+            _ids[state_].clear ();
+            _states[state_].clear ();
+        }
+    }
+
+    void case_sensitive (const bool case_sensitive_)
+    {
+        _case_sensitive = case_sensitive_;
+    }
+
+    bool case_sensitive () const
+    {
+        return _case_sensitive;
+    }
+
+    void locale (std::locale &locale_)
+    {
+        _locale = locale_;
+    }
+
+    const std::locale &locale () const
+    {
+        return _locale;
+    }
+
+    void dot_not_newline (const bool dot_not_newline_)
+    {
+        _dot_not_newline = dot_not_newline_;
+    }
+
+    bool dot_not_newline () const
+    {
+        return _dot_not_newline;
+    }
+
+    std::size_t state (const CharT *name_) const
+    {
+        std::size_t state_ = npos;
+        typename string_size_t_map::const_iterator iter_ =
+            _statemap.find (name_);
+
+        if (iter_ != _statemap.end ())
+        {
+            state_ = iter_->second;
+        }
+
+        return state_;
+    }
+
+    void add_state (const CharT *name_)
+    {
+        validate (name_, true);
+
+        if (_statemap.insert (string_size_t_pair (name_,
+            _statemap.size ())).second)
+        {
+            _regexes.push_back (string_deque ());
+            _ids.push_back (id_vector ());
+            _states.push_back (id_vector ());
+        }
+    }
+
+    void add_macro (const CharT *name_, const CharT *regex_)
+    {
+        add_macro (name_, string (regex_));
+    }
+
+    void add_macro (const CharT *name_, const CharT *regex_start_,
+        const CharT *regex_end_)
+    {
+        add_macro (name_, string (regex_start_, regex_end_));
+    }
+
+    void add_macro (const CharT *name_, const string ®ex_)
+    {
+        validate (name_, false);
+
+        typename string_set::const_iterator iter_ = _macroset.find (name_);
+
+        if (iter_ == _macroset.end ())
+        {
+            _macrodeque.push_back (string_pair (name_, regex_));
+            _macroset.insert (name_);
+        }
+        else
+        {
+            std::basic_stringstream<CharT> ss_;
+            std::ostringstream os_;
+
+            os_ << "Attempt to redefine MACRO '";
+
+            while (*name_)
+            {
+                os_ << ss_.narrow (*name_++, static_cast<CharT> (' '));
+            }
+
+            os_ << "'.";
+            throw runtime_error (os_.str ());
+        }
+    }
+
+    void add (const CharT *regex_, const std::size_t id_)
+    {
+        add (string (regex_), id_);
+    }
+
+    void add (const CharT *regex_start_, const CharT *regex_end_,
+        const std::size_t id_)
+    {
+        add (string (regex_start_, regex_end_), id_);
+    }
+
+    void add (const string ®ex_, const std::size_t id_)
+    {
+        check_for_invalid_id (id_);
+        _regexes[0].push_back (regex_);
+        _ids[0].push_back (id_);
+        _states[0].push_back (0);
+    }
+
+    void add (const CharT *curr_state_, const CharT *regex_,
+        const CharT *new_state_)
+    {
+        add (curr_state_, string (regex_), new_state_);
+    }
+
+    void add (const CharT *curr_state_, const CharT *regex_start_,
+        const CharT *regex_end_, const CharT *new_state_)
+    {
+        add (curr_state_, string (regex_start_, regex_end_), new_state_);
+    }
+
+    void add (const CharT *curr_state_, const string ®ex_,
+        const CharT *new_state_)
+    {
+        add (curr_state_, regex_, 0, new_state_, false);
+    }
+
+    void add (const CharT *curr_state_, const CharT *regex_,
+        const std::size_t id_, const CharT *new_state_)
+    {
+        add (curr_state_, string (regex_), id_, new_state_);
+    }
+
+    void add (const CharT *curr_state_, const CharT *regex_start_,
+        const CharT *regex_end_, const std::size_t id_, const CharT *new_state_)
+    {
+        add (curr_state_, string (regex_start_, regex_end_), id_, new_state_);
+    }
+
+    void add (const CharT *curr_state_, const string ®ex_,
+        const std::size_t id_, const CharT *new_state_)
+    {
+        add (curr_state_, regex_, id_, new_state_, true);
+    }
+
+    void add (const CharT *curr_state_, const basic_rules &rules_)
+    {
+        const string_deque_deque ®exes_ = rules_.regexes ();
+        const id_vector_deque &ids_ = rules_.ids ();
+        typename string_deque_deque::const_iterator state_regex_iter_ =
+            regexes_.begin ();
+        typename string_deque_deque::const_iterator state_regex_end_ =
+            regexes_.end ();
+        typename id_vector_deque::const_iterator state_id_iter_ =
+            ids_.begin ();
+        typename string_deque::const_iterator regex_iter_;
+        typename string_deque::const_iterator regex_end_;
+        typename id_vector::const_iterator id_iter_;
+
+        for (; state_regex_iter_ != state_regex_end_; ++state_regex_iter_)
+        {
+            regex_iter_ = state_regex_iter_->begin ();
+            regex_end_ = state_regex_iter_->end ();
+            id_iter_ = state_id_iter_->begin ();
+
+            for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_)
+            {
+                add (curr_state_, *regex_iter_, *id_iter_, curr_state_);
+            }
+        }
+    }
+
+    const string_size_t_map &statemap () const
+    {
+        return _statemap;
+    }
+
+    const string_pair_deque ¯odeque () const
+    {
+        return _macrodeque;
+    }
+
+    const string_deque_deque ®exes () const
+    {
+        return _regexes;
+    }
+
+    const id_vector_deque &ids () const
+    {
+        return _ids;
+    }
+
+    const id_vector_deque &states () const
+    {
+        return _states;
+    }
+
+    bool empty () const
+    {
+        typename string_deque_deque::const_iterator iter_ = _regexes.begin ();
+        typename string_deque_deque::const_iterator end_ = _regexes.end ();
+        bool empty_ = true;
+
+        for (; iter_ != end_; ++iter_)
+        {
+            if (!iter_->empty ())
+            {
+                empty_ = false;
+                break;
+            }
+        }
+
+        return empty_;
+    }
+
+    static CharT const* initial() 
+    {
+        return detail::initial<CharT>::call();
+    }
+
+private:
+    string_size_t_map _statemap;
+    string_pair_deque _macrodeque;
+    string_set _macroset;
+    string_deque_deque _regexes;
+    id_vector_deque _ids;
+    id_vector_deque _states;
+    bool _case_sensitive;
+    std::locale _locale;
+    bool _dot_not_newline;
+
+    void add (const CharT *curr_state_, const string ®ex_,
+        const std::size_t id_, const CharT *new_state_, const bool check_)
+    {
+        const bool star_ = *curr_state_ == '*' && *(curr_state_ + 1) == 0;
+        const bool dot_ = *new_state_ == '.' && *(new_state_ + 1) == 0;
+
+        if (check_)
+        {
+            check_for_invalid_id (id_);
+        }
+
+        if (!dot_)
+        {
+            validate (new_state_, true);
+        }
+
+        std::size_t new_ = string::npos;
+        typename string_size_t_map::const_iterator iter_;
+        typename string_size_t_map::const_iterator end_ = _statemap.end ();
+        id_vector states_;
+
+        if (!dot_)
+        {
+            iter_ = _statemap.find (new_state_);
+
+            if (iter_ == end_)
+            {
+                std::basic_stringstream<CharT> ss_;
+                std::ostringstream os_;
+
+                os_ << "Unknown state name '";
+
+                while (*new_state_)
+                {
+                    os_ << ss_.narrow (*new_state_++, ' ');
+                }
+
+                os_ << "'.";
+                throw runtime_error (os_.str ());
+            }
+
+            new_ = iter_->second;
+        }
+
+        if (star_)
+        {
+            const std::size_t size_ = _statemap.size ();
+
+            for (std::size_t i_ = 0; i_ < size_; ++i_)
+            {
+                states_.push_back (i_);
+            }
+        }
+        else
+        {
+            const CharT *start_ = curr_state_;
+            string state_;
+
+            while (*curr_state_)
+            {
+                while (*curr_state_ && *curr_state_ != ',')
+                {
+                    ++curr_state_;
+                }
+
+                state_.assign (start_, curr_state_);
+
+                if (*curr_state_)
+                {
+                    ++curr_state_;
+                    start_ = curr_state_;
+                }
+
+                validate (state_.c_str (), true);
+                iter_ = _statemap.find (state_.c_str ());
+
+                if (iter_ == end_)
+                {
+                    std::basic_stringstream<CharT> ss_;
+                    std::ostringstream os_;
+
+                    os_ << "Unknown state name '";
+
+                    while (*curr_state_)
+                    {
+                        os_ << ss_.narrow (*curr_state_++, ' ');
+                    }
+
+                    os_ << "'.";
+                    throw runtime_error (os_.str ());
+                }
+
+                states_.push_back (iter_->second);
+            }
+        }
+
+        for (std::size_t i_ = 0, size_ = states_.size (); i_ < size_; ++i_)
+        {
+            const std::size_t curr_ = states_[i_];
+
+            _regexes[curr_].push_back (regex_);
+            _ids[curr_].push_back (id_);
+            _states[curr_].push_back (dot_ ? curr_ : new_);
+        }
+    }
+
+    void validate (const CharT *name_, const bool comma_) const
+    {
+again:
+        const CharT *start_ = name_;
+
+        if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') &&
+            !(*name_ >= 'a' && *name_ <= 'z'))
+        {
+            std::basic_stringstream<CharT> ss_;
+            std::ostringstream os_;
+
+            os_ << "Invalid name '";
+
+            while (*name_)
+            {
+                os_ << ss_.narrow (*name_++, ' ');
+            }
+
+            os_ << "'.";
+            throw runtime_error (os_.str ());
+        }
+        else if (*name_)
+        {
+            ++name_;
+        }
+
+        while (*name_)
+        {
+            if (*name_ == ',' && comma_)
+            {
+                ++name_;
+                goto again;
+            }
+
+            if (*name_ != '_' && *name_ != '-' &&
+                !(*name_ >= 'A' && *name_ <= 'Z') &&
+                !(*name_ >= 'a' && *name_ <= 'z') &&
+                !(*name_ >= '0' && *name_ <= '9'))
+            {
+                std::basic_stringstream<CharT> ss_;
+                std::ostringstream os_;
+
+                os_ << "Invalid name '";
+
+                while (*name_)
+                {
+                    os_ << ss_.narrow (*name_++, ' ');
+                }
+
+                os_ << "'.";
+                throw runtime_error (os_.str ());
+            }
+
+            ++name_;
+        }
+
+        if (name_ - start_ > static_cast<std::ptrdiff_t>(max_macro_len))
+        {
+            std::basic_stringstream<CharT> ss_;
+            std::ostringstream os_;
+
+            os_ << "Name '";
+
+            while (*name_)
+            {
+                os_ << ss_.narrow (*name_++, ' ');
+            }
+
+            os_ << "' too long.";
+            throw runtime_error (os_.str ());
+        }
+    }
+
+    void check_for_invalid_id (const std::size_t id_) const
+    {
+        switch (id_)
+        {
+        case 0:
+            throw runtime_error ("id 0 is reserved for EOF.");
+        case npos:
+            throw runtime_error ("id npos is reserved for the "
+                "UNKNOWN token.");
+        default:
+            // OK
+            break;
+        }
+    }
+};
+
+typedef basic_rules<char> rules;
+typedef basic_rules<wchar_t> wrules;
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/runtime_error.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/runtime_error.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,26 @@
+// runtime_error.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_RUNTIME_ERROR_HPP
+#define BOOST_LEXER_RUNTIME_ERROR_HPP
+
+#include <stdexcept>
+
+namespace boost
+{
+namespace lexer
+{
+class runtime_error : public std::runtime_error
+{
+public:
+    runtime_error (const std::string &what_arg_) :
+        std::runtime_error (what_arg_)
+    {
+    }
+};
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/serialise.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/serialise.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,30 @@
+// examples/serialise.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_SERIALISE_HPP
+#define BOOST_LEXER_SERIALISE_HPP
+
+#include "state_machine.hpp"
+#include <boost/serialization/vector.hpp>
+
+namespace boost
+{
+namespace lexer
+{
+// IMPORTANT! This won't work if you don't enable RTTI!
+template<class Archive>
+void serialise (Archive &ar_, state_machine &sm_, unsigned int version_)
+{
+    ar_ & version_;
+    ar_ & *sm_._lookup;
+    ar_ & sm_._dfa_alphabet;
+    ar_ & *sm_._dfa;
+    ar_ & sm_._seen_BOL_assertion;
+    ar_ & sm_._seen_EOL_assertion;
+}
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/size_t.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/size_t.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+// size_t.h
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_SIZE_T_H
+#define BOOST_LEXER_SIZE_T_H
+
+#include <stddef.h> // ptrdiff_t
+
+#if defined _MSC_VER && _MSC_VER <= 1200
+namespace std
+{
+    using ::ptrdiff_t;
+    using ::size_t;
+}
+#else
+#include <string>
+#endif
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/state_machine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/state_machine.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,157 @@
+// state_machine.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_STATE_MACHINE_HPP
+#define BOOST_LEXER_STATE_MACHINE_HPP
+
+#include <algorithm>
+#include "char_state_machine.hpp"
+#include "consts.hpp"
+#include <deque>
+#include <map>
+#include "containers/ptr_vector.hpp"
+#include "size_t.hpp"
+#include <string>
+
+namespace boost
+{
+namespace lexer
+{
+struct state_machine
+{
+    typedef std::vector<std::size_t> size_t_vector;
+    typedef internal::ptr_vector<size_t_vector> size_t_vector_vector;
+
+    size_t_vector_vector _lookup;
+    size_t_vector _dfa_alphabet;
+    size_t_vector_vector _dfa;
+    bool _seen_BOL_assertion;
+    bool _seen_EOL_assertion;
+
+    state_machine () :
+        _seen_BOL_assertion (false),
+        _seen_EOL_assertion (false)
+    {
+    }
+
+    bool empty () const
+    {
+        return _lookup->empty () && _dfa_alphabet.empty () &&
+            _dfa->empty ();
+    }
+
+    void clear ()
+    {
+        _lookup.clear ();
+        _dfa_alphabet.clear ();
+        _dfa.clear ();
+        _seen_BOL_assertion = false;
+        _seen_EOL_assertion = false;
+    }
+
+    void swap (state_machine &sm_)
+    {
+        _lookup->swap (*sm_._lookup);
+        _dfa_alphabet.swap (sm_._dfa_alphabet);
+        _dfa->swap (*sm_._dfa);
+        std::swap (_seen_BOL_assertion, sm_._seen_BOL_assertion);
+        std::swap (_seen_EOL_assertion, sm_._seen_EOL_assertion);
+    }
+
+    template<typename CharT>
+    void human_readable (basic_char_state_machine<CharT> &sm_) const
+    {
+        const std::size_t max_ = sizeof (CharT) == 1 ?
+            num_chars : num_wchar_ts;
+        const std::size_t start_states_ = _dfa->size ();
+
+        sm_.clear ();
+        sm_._sm_vector.resize (start_states_);
+
+        for (std::size_t start_state_index_ = 0;
+            start_state_index_ < start_states_; ++start_state_index_)
+        {
+            const size_t_vector *lu_ = _lookup[start_state_index_];
+            const std::size_t alphabet_ = _dfa_alphabet[start_state_index_] - dfa_offset;
+            std::vector<std::basic_string<CharT> > chars_ (alphabet_);
+            const std::size_t states_ = _dfa[start_state_index_]->size () /
+                (alphabet_ + dfa_offset);
+            const std::size_t *read_ptr_ = &_dfa[start_state_index_]->
+                front () + alphabet_ + dfa_offset;
+
+            sm_._sm_vector[start_state_index_].resize (states_ - 1);
+
+            for (std::size_t alpha_index_ = 0; alpha_index_ < max_;
+                ++alpha_index_)
+            {
+                const std::size_t col_ = lu_->at (alpha_index_);
+
+                if (col_ != dead_state_index)
+                {
+                    chars_[col_ - dfa_offset] += static_cast<CharT>
+                        (alpha_index_);
+                }
+            }
+
+            for (std::size_t state_index_ = 1; state_index_ < states_;
+                ++state_index_)
+            {
+                typename basic_char_state_machine<CharT>::state *state_ =
+                    &sm_._sm_vector[start_state_index_][state_index_ - 1];
+
+                state_->_end_state = *read_ptr_ != 0;
+                state_->_id = *(read_ptr_ + id_index);
+                state_->_state = *(read_ptr_ + state_index);
+                state_->_bol_index = *(read_ptr_ + bol_index) - 1;
+                state_->_eol_index = *(read_ptr_ + eol_index) - 1;
+                read_ptr_ += dfa_offset;
+
+                for (std::size_t col_index_ = 0; col_index_ < alphabet_;
+                    ++col_index_, ++read_ptr_)
+                {
+                    const std::size_t transition_ = *read_ptr_;
+
+                    if (transition_ != 0)
+                    {
+                        const std::size_t i_ = transition_ - 1;
+                        typename basic_char_state_machine<CharT>::state::
+                            size_t_string_token_map::iterator iter_ =
+                            state_->_transitions.find (i_);
+
+                        if (iter_ == state_->_transitions.end ())
+                        {
+                            basic_string_token<CharT> token_
+                                (false, chars_[col_index_]);
+                            typename basic_char_state_machine<CharT>::
+                                state::size_t_string_token_pair pair_
+                                (i_, token_);
+
+                            state_->_transitions.insert (pair_);
+                        }
+                        else
+                        {
+                            iter_->second._charset += chars_[col_index_];
+                        }
+                    }
+                }
+
+                for (typename basic_char_state_machine<CharT>::state::
+                    size_t_string_token_map::iterator iter_ =
+                    state_->_transitions.begin (),
+                    end_ = state_->_transitions.end ();
+                    iter_ != end_; ++iter_)
+                {
+                    std::sort (iter_->second._charset.begin (),
+                        iter_->second._charset.end ());
+                    iter_->second.normalise ();
+                }
+            }
+        }
+    }
+};
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/string_token.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/string_token.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,336 @@
+// string_token.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_STRING_TOKEN_HPP
+#define BOOST_LEXER_STRING_TOKEN_HPP
+
+#include <algorithm>
+#include "size_t.hpp"
+#include "consts.hpp" // num_chars, num_wchar_ts
+#include <string>
+
+namespace boost
+{
+namespace lexer
+{
+template<typename CharT>
+struct basic_string_token
+{
+    typedef std::basic_string<CharT> string;
+
+    bool _negated;
+    string _charset;
+
+    basic_string_token () :
+        _negated (false)
+    {
+    }
+
+    basic_string_token (const bool negated_, const string &charset_) :
+        _negated (negated_),
+        _charset (charset_)
+    {
+    }
+
+    void remove_duplicates ()
+    {
+        const CharT *start_ = _charset.c_str ();
+        const CharT *end_ = start_ + _charset.size ();
+
+        // Optimisation for very large charsets:
+        // sorting via pointers is much quicker than
+        // via iterators...
+        std::sort (const_cast<CharT *> (start_), const_cast<CharT *> (end_));
+        _charset.erase (std::unique (_charset.begin (), _charset.end ()),
+            _charset.end ());
+    }
+
+    void normalise ()
+    {
+        const std::size_t max_chars_ = sizeof(CharT) == 1 ?
+            num_chars : num_wchar_ts;
+
+        if (_charset.length () == max_chars_)
+        {
+            _negated = !_negated;
+#if defined _MSC_VER && _MSC_VER <= 1200
+            _charset.erase ();
+#else
+            _charset.clear ();
+#endif
+        }
+        else if (_charset.length () > max_chars_ / 2)
+        {
+            negate ();
+        }
+    }
+
+    void negate ()
+    {
+        const std::size_t max_chars_ = sizeof(CharT) == 1 ?
+            num_chars : num_wchar_ts;
+        CharT curr_char_ = sizeof (CharT) == 1 ? -128 : 0;
+        string temp_;
+        const CharT *curr_ = _charset.c_str ();
+        const CharT *chars_end_ = curr_ + _charset.size ();
+
+        _negated = !_negated;
+        temp_.resize (max_chars_ - _charset.size ());
+
+        CharT *ptr_ = const_cast<CharT *> (temp_.c_str ());
+        std::size_t i_ = 0;
+
+        while (curr_ < chars_end_)
+        {
+            while (*curr_ > curr_char_)
+            {
+                *ptr_ = curr_char_;
+                ++ptr_;
+                ++curr_char_;
+                ++i_;
+            }
+
+            ++curr_char_;
+            ++curr_;
+            ++i_;
+        }
+
+        for (; i_ < max_chars_; ++i_)
+        {
+            *ptr_ = curr_char_;
+            ++ptr_;
+            ++curr_char_;
+        }
+
+        _charset = temp_;
+    }
+
+    bool operator < (const basic_string_token &rhs_) const
+    {
+        return _negated < rhs_._negated ||
+            (_negated == rhs_._negated && _charset < rhs_._charset);
+    }
+
+    bool empty () const
+    {
+        return _charset.empty () && !_negated;
+    }
+
+    bool any () const
+    {
+        return _charset.empty () && _negated;
+    }
+
+    void clear ()
+    {
+        _negated = false;
+#if defined _MSC_VER && _MSC_VER <= 1200
+            _charset.erase ();
+#else
+            _charset.clear ();
+#endif
+    }
+
+    void intersect (basic_string_token &rhs_, basic_string_token &overlap_)
+    {
+        if (any () && rhs_.any () || (_negated == rhs_._negated &&
+            !any () && !rhs_.any ()))
+        {
+            intersect_same_types (rhs_, overlap_);
+        }
+        else
+        {
+            intersect_diff_types (rhs_, overlap_);
+        }
+    }
+
+private:
+    void intersect_same_types (basic_string_token &rhs_, basic_string_token &overlap_)
+    {
+        if (any ())
+        {
+            clear ();
+            overlap_._negated = true;
+            rhs_.clear ();
+        }
+        else
+        {
+            typename string::iterator iter_ = _charset.begin ();
+            typename string::iterator end_ = _charset.end ();
+            typename string::iterator rhs_iter_ = rhs_._charset.begin ();
+            typename string::iterator rhs_end_ = rhs_._charset.end ();
+
+            overlap_._negated = _negated;
+
+            while (iter_ != end_ && rhs_iter_ != rhs_end_)
+            {
+                if (*iter_ < *rhs_iter_)
+                {
+                    ++iter_;
+                }
+                else if (*iter_ > *rhs_iter_)
+                {
+                    ++rhs_iter_;
+                }
+                else
+                {
+                    overlap_._charset += *iter_;
+                    iter_ = _charset.erase (iter_);
+                    end_ = _charset.end ();
+                    rhs_iter_ = rhs_._charset.erase (rhs_iter_);
+                    rhs_end_ = rhs_._charset.end ();
+                }
+            }
+
+            if (_negated)
+            {
+                // duplicates already merged, so safe to merge
+                // using std lib.
+
+                // src, dest
+                merge (_charset, overlap_._charset);
+                // duplicates already merged, so safe to merge
+                // using std lib.
+
+                // src, dest
+                merge (rhs_._charset, overlap_._charset);
+                _negated = false;
+                rhs_._negated = false;
+                std::swap (_charset, rhs_._charset);
+                normalise ();
+                overlap_.normalise ();
+                rhs_.normalise ();
+            }
+            else if (!overlap_._charset.empty ())
+            {
+                normalise ();
+                overlap_.normalise ();
+                rhs_.normalise ();
+            }
+        }
+    }
+
+    void intersect_diff_types (basic_string_token &rhs_,
+        basic_string_token &overlap_)
+    {
+        if (any ())
+        {
+            intersect_any (rhs_, overlap_);
+        }
+        else if (_negated)
+        {
+            intersect_negated (rhs_, overlap_);
+        }
+        else // _negated == false
+        {
+            intersect_charset (rhs_, overlap_);
+        }
+    }
+
+    void intersect_any (basic_string_token &rhs_, basic_string_token &overlap_)
+    {
+        if (rhs_._negated)
+        {
+            rhs_.intersect_negated (*this, overlap_);
+        }
+        else // rhs._negated == false
+        {
+            rhs_.intersect_charset (*this, overlap_);
+        }
+    }
+
+    void intersect_negated (basic_string_token &rhs_,
+        basic_string_token &overlap_)
+    {
+        if (rhs_.any ())
+        {
+            overlap_._negated = true;
+            overlap_._charset = _charset;
+            rhs_._negated = false;
+            rhs_._charset = _charset;
+            clear ();
+        }
+        else // rhs._negated == false
+        {
+            rhs_.intersect_charset (*this, overlap_);
+        }
+    }
+
+    void intersect_charset (basic_string_token &rhs_,
+        basic_string_token &overlap_)
+    {
+        if (rhs_.any ())
+        {
+            overlap_._charset = _charset;
+            rhs_._negated = true;
+            rhs_._charset = _charset;
+            clear ();
+        }
+        else // rhs_._negated == true
+        {
+            typename string::iterator iter_ = _charset.begin ();
+            typename string::iterator end_ = _charset.end ();
+            typename string::iterator rhs_iter_ = rhs_._charset.begin ();
+            typename string::iterator rhs_end_ = rhs_._charset.end ();
+
+            while (iter_ != end_ && rhs_iter_ != rhs_end_)
+            {
+                if (*iter_ < *rhs_iter_)
+                {
+                    overlap_._charset += *iter_;
+                    rhs_iter_ = rhs_._charset.insert (rhs_iter_, *iter_);
+                    ++rhs_iter_;
+                    rhs_end_ = rhs_._charset.end ();
+                    iter_ = _charset.erase (iter_);
+                    end_ = _charset.end ();
+                }
+                else if (*iter_ > *rhs_iter_)
+                {
+                    ++rhs_iter_;
+                }
+                else
+                {
+                    ++iter_;
+                    ++rhs_iter_;
+                }
+            }
+
+            if (iter_ != end_)
+            {
+                // nothing bigger in rhs_ than iter_,
+                // so safe to merge using std lib.
+                string temp_ (iter_, end_);
+
+                // src, dest
+                merge (temp_, overlap_._charset);
+                _charset.erase (iter_, end_);
+            }
+
+            if (!overlap_._charset.empty ())
+            {
+                merge (overlap_._charset, rhs_._charset);
+                // possible duplicates, so check for any and erase.
+                rhs_._charset.erase (std::unique (rhs_._charset.begin (),
+                    rhs_._charset.end ()), rhs_._charset.end ());
+                normalise ();
+                overlap_.normalise ();
+                rhs_.normalise ();
+            }
+        }
+    }
+
+    void merge (string &src_, string &dest_)
+    {
+        string tmp_ (src_.size () + dest_.size (), 0);
+
+        std::merge (src_.begin (), src_.end (), dest_.begin (), dest_.end (),
+            tmp_.begin ());
+        dest_ = tmp_;
+    }
+};
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/lexer/tokeniser.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/lexer/tokeniser.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,298 @@
+// examples/tokeniser.hpp
+// Copyright (c) 2007 Ben Hanson
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_LEXER_EXAMPLES_TOKENISER_HPP
+#define BOOST_LEXER_EXAMPLES_TOKENISER_HPP
+
+#include "char_traits.hpp"
+#include "consts.hpp"
+#include <boost/detail/iterator.hpp>
+#include "size_t.hpp"
+#include "state_machine.hpp"
+
+namespace boost
+{
+namespace lexer
+{
+template<typename Iterator, typename Traits =
+    char_traits<typename detail::iterator_traits<Iterator>::value_type> >
+struct basic_tokeniser
+{
+    static std::size_t next (const state_machine &state_machine_,
+        std::size_t &start_state_, const Iterator &start_,
+        Iterator &start_token_, const Iterator &end_)
+    {
+        if (start_token_ == end_) return 0;
+
+    again:
+        const std::size_t * lookup_ = &state_machine_._lookup[start_state_]->
+            front ();
+        std::size_t dfa_alphabet_ = state_machine_._dfa_alphabet[start_state_];
+        const std::size_t *dfa_ = &state_machine_._dfa[start_state_]->front ();
+        const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
+        Iterator curr_ = start_token_;
+        bool end_state_ = *ptr_ != 0;
+        std::size_t id_ = *(ptr_ + id_index);
+        Iterator end_token_ = start_token_;
+
+        while (curr_ < end_)
+        {
+            const std::size_t BOL_state_ = ptr_[bol_index];
+            const std::size_t EOL_state_ = ptr_[eol_index];
+
+            if (BOL_state_ && (start_token_ == start_ ||
+                *(start_token_ - 1) == '\n'))
+            {
+                ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
+            }
+            else if (EOL_state_ && *curr_ == '\n')
+            {
+                ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+            }
+            else
+            {
+                const std::size_t state_ =
+                    ptr_[lookup_[static_cast<typename Traits::index_type>
+                    (*curr_++)]];
+
+                if (state_ == 0)
+                {
+                    break;
+                }
+
+                ptr_ = &dfa_[state_ * dfa_alphabet_];
+            }
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                start_state_ = *(ptr_ + state_index);
+                end_token_ = curr_;
+            }
+        }
+
+        const std::size_t EOL_state_ = ptr_[eol_index];
+
+        if (EOL_state_ && curr_ == end_)
+        {
+            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                start_state_ = *(ptr_ + state_index);
+                end_token_ = curr_;
+            }
+        }
+
+        if (end_state_)
+        {
+            // return longest match
+            start_token_ = end_token_;
+
+            if (id_ == 0) goto again;
+        }
+        else
+        {
+            // No match causes char to be skipped
+            ++start_token_;
+            id_ = npos;
+        }
+
+        return id_;
+    }
+
+    static std::size_t next (const state_machine &state_machine_,
+        std::size_t &start_state_, Iterator &start_token_,
+        Iterator const &end_)
+    {
+        if (start_token_ == end_) return 0;
+
+    again:
+        const std::size_t * lookup_ = &state_machine_._lookup[start_state_]->
+            front ();
+        std::size_t dfa_alphabet_ = state_machine_._dfa_alphabet[start_state_];
+        const std::size_t *dfa_ = &state_machine_._dfa[start_state_]->front ();
+        const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
+        Iterator curr_ = start_token_;
+        bool end_state_ = *ptr_ != 0;
+        std::size_t id_ = *(ptr_ + id_index);
+        Iterator end_token_ = start_token_;
+
+        while (curr_ < end_)
+        {
+            const std::size_t state_ = ptr_[lookup_[static_cast
+                <typename Traits::index_type>(*curr_++)]];
+
+            if (state_ == 0)
+            {
+                break;
+            }
+
+            ptr_ = &dfa_[state_ * dfa_alphabet_];
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                start_state_ = *(ptr_ + state_index);
+                end_token_ = curr_;
+            }
+        }
+
+        if (end_state_)
+        {
+            // return longest match
+            start_token_ = end_token_;
+
+            if (id_ == 0) goto again;
+        }
+        else
+        {
+            // No match causes char to be skipped
+            ++start_token_;
+            id_ = npos;
+        }
+
+        return id_;
+    }
+
+    static std::size_t next (const std::size_t * const lookup_,
+        const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
+        Iterator const &start_, Iterator &start_token_,
+        Iterator const &end_)
+    {
+        if (start_token_ == end_) return 0;
+
+        const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
+        Iterator curr_ = start_token_;
+        bool end_state_ = *ptr_ != 0;
+        std::size_t id_ = *(ptr_ + id_index);
+        Iterator end_token_ = start_token_;
+
+        while (curr_ < end_)
+        {
+            const std::size_t BOL_state_ = ptr_[bol_index];
+            const std::size_t EOL_state_ = ptr_[eol_index];
+
+            if (BOL_state_ && (start_token_ == start_ ||
+                *(start_token_ - 1) == '\n'))
+            {
+                ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
+            }
+            else if (EOL_state_ && *curr_ == '\n')
+            {
+                ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+            }
+            else
+            {
+                const std::size_t state_ =
+                    ptr_[lookup_[static_cast<typename Traits::index_type>
+                    (*curr_++)]];
+
+                if (state_ == 0)
+                {
+                    break;
+                }
+
+                ptr_ = &dfa_[state_ * dfa_alphabet_];
+            }
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                end_token_ = curr_;
+            }
+        }
+
+        const std::size_t EOL_state_ = ptr_[eol_index];
+
+        if (EOL_state_ && curr_ == end_)
+        {
+            ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                end_token_ = curr_;
+            }
+        }
+
+        if (end_state_)
+        {
+            // return longest match
+            start_token_ = end_token_;
+        }
+        else
+        {
+            // No match causes char to be skipped
+            ++start_token_;
+            id_ = npos;
+        }
+
+        return id_;
+    }
+
+    static std::size_t next (const std::size_t * const lookup_,
+        const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
+        Iterator &start_token_, Iterator const &end_)
+    {
+        if (start_token_ == end_) return 0;
+
+        const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
+        Iterator curr_ = start_token_;
+        bool end_state_ = *ptr_ != 0;
+        std::size_t id_ = *(ptr_ + id_index);
+        Iterator end_token_ = start_token_;
+
+        while (curr_ < end_)
+        {
+            const std::size_t state_ = ptr_[lookup_[static_cast
+                <typename Traits::index_type>(*curr_++)]];
+
+            if (state_ == 0)
+            {
+                break;
+            }
+
+            ptr_ = &dfa_[state_ * dfa_alphabet_];
+
+            if (*ptr_)
+            {
+                end_state_ = true;
+                id_ = *(ptr_ + id_index);
+                end_token_ = curr_;
+            }
+        }
+
+        if (end_state_)
+        {
+            // return longest match
+            start_token_ = end_token_;
+        }
+        else
+        {
+            // No match causes char to be skipped
+            ++start_token_;
+            id_ = npos;
+        }
+
+        return id_;
+    }
+};
+
+typedef basic_tokeniser<std::string::iterator> iter_tokeniser;
+typedef basic_tokeniser<std::wstring::iterator> iter_wtokeniser;
+typedef basic_tokeniser<const char *> ptr_tokeniser;
+typedef basic_tokeniser<const wchar_t *> ptr_wtokeniser;
+
+}
+}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/math/detail/fp_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/math/detail/fp_traits.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,576 @@
+// fp_traits.hpp
+
+#ifndef BOOST_MATH_FP_TRAITS_HPP
+#define BOOST_MATH_FP_TRAITS_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
+#   error The VAX floating point mode on VMS is not supported.
+#endif
+
+#include <cstring>
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+
+//------------------------------------------------------------------------------
+
+namespace boost {
+namespace math {
+namespace detail {
+
+//------------------------------------------------------------------------------
+
+/*
+Most processors support three different floating point precisions:
+single precision (32 bits), double precision (64 bits)
+and extended double precision (>64 bits)
+
+Note that the C++ type long double can be implemented
+both as double precision and extended double precision.
+*/
+
+struct single_precision_tag {};
+struct double_precision_tag {};
+struct extended_double_precision_tag {};
+
+//------------------------------------------------------------------------------
+
+/*
+template<class T, class U> struct fp_traits_impl;
+
+  This is traits class that describes the binary structure of floating
+  point numbers of C++ type T and precision U
+
+Requirements: 
+
+  T = float, double or long double
+  U = single_precision_tag, double_precision_tag
+      or extended_double_precision_tag
+
+Typedef members:
+
+  bits -- the target type when copying the leading bytes of a floating
+      point number. It is a typedef for uint32_t or uint64_t.
+
+  coverage -- tells us whether all bytes are copied or not.
+      It is a typedef for all_bits or not_all_bits.
+
+Static data members:
+
+  sign, exponent, flag, mantissa -- bit masks that give the meaning of the bits
+      in the leading bytes.
+
+Static function members:
+
+  init() -- initializes the static data members, if needed.
+            (Is a no-op in the specialized versions of the template.)
+
+  get_bits(), set_bits() -- provide access to the leading bytes.
+*/
+
+struct all_bits {};
+struct not_all_bits {};
+
+// Generic version -------------------------------------------------------------
+
+// The generic version uses run time initialization to determine the floating
+// point format. It is capable of handling most formats,
+// but not the Motorola 68K extended double precision format.
+
+// Currently the generic version is used only for extended double precision
+// on Itanium. In all other cases there are specializations of the template
+// that use compile time initialization.
+
+template<class T> struct uint32_t_coverage
+{
+    typedef not_all_bits type;
+};
+
+template<> struct uint32_t_coverage<single_precision_tag>
+{
+    typedef all_bits type;
+};
+
+template<class T, class U> struct fp_traits_impl
+{
+    typedef uint32_t bits;
+    typedef BOOST_DEDUCED_TYPENAME uint32_t_coverage<U>::type coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
+    static uint32_t exponent;
+    static uint32_t flag;
+    static uint32_t mantissa;
+
+    static void init()
+    {
+        if(is_init_) return;
+        do_init_();
+        is_init_ = true;
+    }
+
+    static void get_bits(T x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+    }
+
+    static void set_bits(T& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+    }
+
+private:
+    static size_t offset_;
+    static bool is_init_;
+    static void do_init_();
+};
+
+//..............................................................................
+
+template<class T, class U> uint32_t fp_traits_impl<T,U>::exponent;
+template<class T, class U> uint32_t fp_traits_impl<T,U>::flag;
+template<class T, class U> uint32_t fp_traits_impl<T,U>::mantissa;
+template<class T, class U> size_t   fp_traits_impl<T,U>::offset_;
+template<class T, class U> bool     fp_traits_impl<T,U>::is_init_;
+
+// In a single-threaded program, do_init will be called exactly once.
+// In a multi-threaded program, do_init may be called simultaneously
+// by more then one thread. That should not be a problem.
+
+//..............................................................................
+
+template<class T, class U> void fp_traits_impl<T,U>::do_init_()
+{
+    T x = static_cast<T>(3) / static_cast<T>(4);
+    // sign bit = 0
+    // exponent: first and last bit = 0, all other bits  = 1
+    // flag bit (if present) = 1
+    // mantissa: first bit = 1, all other bits = 0
+
+    uint32_t a;
+
+    for(size_t k = 0; k <= sizeof(T) - 4; ++k) {
+
+        memcpy(&a, reinterpret_cast<unsigned char*>(&x) + k, 4);
+
+        switch(a) {
+
+        case 0x3f400000:      // IEEE single precision format
+
+            offset_  = k;      
+            exponent = 0x7f800000;
+            flag     = 0x00000000;
+            mantissa = 0x007fffff;
+            return;
+
+        case 0x3fe80000:      // IEEE double precision format 
+                              // and PowerPC extended double precision format
+            offset_  = k;      
+            exponent = 0x7ff00000;
+            flag     = 0x00000000;
+            mantissa = 0x000fffff;
+            return;
+
+        case 0x3ffe0000:      // Motorola extended double precision format
+
+            // Must not get here. Must be handled by specialization.
+            // To get accurate cutoff between normals and subnormals
+            // we must use the flag bit that is in the 5th byte.
+            // Otherwise this cutoff will be off by a factor 2.
+            // If we do get here, then we have failed to detect the Motorola
+            // processor at compile time.
+
+            BOOST_ASSERT(false);        
+            return;
+
+        case 0x3ffe8000:      // IEEE extended double precision format
+                              // with 15 exponent bits
+            offset_  = k;      
+            exponent = 0x7fff0000;
+            flag     = 0x00000000;
+            mantissa = 0x0000ffff;
+            return;
+
+        case 0x3ffec000:      // Intel extended double precision format
+
+            offset_  = k;
+            exponent = 0x7fff0000;
+            flag     = 0x00008000;
+            mantissa = 0x00007fff;
+            return;
+
+        default:
+            continue;
+        }
+    }
+
+    BOOST_ASSERT(false); 
+
+    // Unknown format.
+}
+
+
+// float (32 bits) -------------------------------------------------------------
+
+template<> struct fp_traits_impl<float, single_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0x00000000);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x007fffff);
+
+    static void init() {}
+    static void get_bits(float x, uint32_t& a) { memcpy(&a, &x, 4); }
+    static void set_bits(float& x, uint32_t a) { memcpy(&x, &a, 4); }
+};
+
+
+// double (64 bits) ------------------------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template<> struct fp_traits_impl<double, double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+    static void init() {}
+
+    static void get_bits(double x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+    }
+
+    static void set_bits(double& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+    }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+    BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_impl<double, double_precision_tag>
+{
+    typedef uint64_t bits;
+    typedef all_bits coverage;
+
+    static const uint64_t sign     = (uint64_t)0x80000000 << 32;
+    static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
+    static const uint64_t flag     = 0;
+    static const uint64_t mantissa
+        = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
+
+    static void init() {}
+    static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); }
+    static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }
+};
+
+#endif
+
+
+// long double (64 bits) -------------------------------------------------------
+
+#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+template<> struct fp_traits_impl<long double, double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+    static void init() {}
+
+    static void get_bits(long double x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+    }
+
+    static void set_bits(long double& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+    }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 4);
+#else
+    BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+//..............................................................................
+
+#else
+
+template<> struct fp_traits_impl<long double, double_precision_tag>
+{
+    typedef uint64_t bits;
+    typedef all_bits coverage;
+
+    static const uint64_t sign     = (uint64_t)0x80000000 << 32;
+    static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
+    static const uint64_t flag     = 0;
+    static const uint64_t mantissa
+        = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
+
+    static void init() {}
+    static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); }
+    static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }
+};
+
+#endif
+
+
+// long double (>64 bits), x86 and x64 -----------------------------------------
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+    || defined(__amd64) || defined(__amd64__)  || defined(_M_AMD64) \
+    || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
+
+// Intel extended double precision format (80 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0x00008000);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
+
+    static void init() {}
+
+    static void get_bits(long double x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
+    }
+
+    static void set_bits(long double& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
+    }
+};
+
+
+// long double (>64 bits), Itanium ---------------------------------------------
+
+#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+
+// The floating point format is unknown at compile time
+// No template specialization is provided.
+// The generic definition is used.
+
+// The Itanium supports both
+// the Intel extended double precision format (80 bits) and
+// the IEEE extended double precision format with 15 exponent bits (128 bits).
+
+
+// long double (>64 bits), PowerPC ---------------------------------------------
+
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
+    || defined(__ppc) || defined(__ppc__) || defined(__PPC__)
+
+// PowerPC extended double precision format (128 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0x00000000);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
+
+    static void init() {}
+
+    static void get_bits(long double x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+    }
+
+    static void set_bits(long double& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+    }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+    BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+
+// long double (>64 bits), Motorola 68K ----------------------------------------
+
+#elif defined(__m68k) || defined(__m68k__) \
+    || defined(__mc68000) || defined(__mc68000__) \
+
+// Motorola extended double precision format (96 bits)
+
+// It is the same format as the Intel extended double precision format,
+// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
+// 3) the flag bit is not set for infinity
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0x00008000);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
+
+    static void init() {}
+
+    // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
+
+    static void get_bits(long double x, uint32_t& a)
+    {
+        memcpy(&a, &x, 2);
+        memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
+               reinterpret_cast<const unsigned char*>(&x) + 4, 2);
+    }
+
+    static void set_bits(long double& x, uint32_t a)
+    {
+        memcpy(&x, &a, 2);
+        memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
+               reinterpret_cast<const unsigned char*>(&a) + 2, 2);
+    }
+};
+
+
+// long double (>64 bits), All other processors --------------------------------
+
+#else
+
+// IEEE extended double precision format with 15 exponent bits (128 bits)
+
+template<> struct fp_traits_impl<long double, extended_double_precision_tag>
+{
+    typedef uint32_t bits;
+    typedef not_all_bits coverage;
+
+    BOOST_STATIC_CONSTANT(uint32_t, sign     = 0x80000000);
+    BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
+    BOOST_STATIC_CONSTANT(uint32_t, flag     = 0x00000000);
+    BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff);
+
+    static void init() {}
+
+    static void get_bits(long double x, uint32_t& a)
+    {
+        memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
+    }
+
+    static void set_bits(long double& x, uint32_t a)
+    {
+        memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
+    }
+
+private:
+
+#if defined(BOOST_BIG_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 0);
+#elif defined(BOOST_LITTLE_ENDIAN)
+    BOOST_STATIC_CONSTANT(int, offset_ = 12);
+#else
+    BOOST_STATIC_ASSERT(false);
+#endif
+};
+
+#endif
+
+
+//------------------------------------------------------------------------------
+
+// size_to_precision is a type switch for converting a C++ floating point type
+// to the corresponding precision type.
+
+template<int n> struct size_to_precision;
+
+template<> struct size_to_precision<4>
+{
+    typedef single_precision_tag type;
+};
+
+template<> struct size_to_precision<8>
+{
+    typedef double_precision_tag type;
+};
+
+template<> struct size_to_precision<10>
+{
+    typedef extended_double_precision_tag type;
+};
+
+template<> struct size_to_precision<12>
+{
+    typedef extended_double_precision_tag type;
+};
+
+template<> struct size_to_precision<16>
+{
+    typedef extended_double_precision_tag type;
+};
+
+// fp_traits is a type switch that selects the right fp_traits_impl
+
+template<class T> struct fp_traits
+{
+    BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
+    typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision;
+    typedef fp_traits_impl<T, precision> type;
+};
+
+
+//------------------------------------------------------------------------------
+
+}   // namespace detail
+}   // namespace math
+}   // namespace boost
+
+#endif
Added: trunk/boost/spirit/home/support/detail/math/fpclassify.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/math/fpclassify.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,229 @@
+// fpclassify.hpp
+
+#ifndef BOOST_MATH_FPCLASSIFY_HPP
+#define BOOST_MATH_FPCLASSIFY_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+The following algorithm is used:
+
+  If all exponent bits, the flag bit (if there is one), 
+  and all mantissa bits are 0, then the number is zero.
+
+  If all exponent bits and the flag bit (if there is one) are 0, 
+  and at least one mantissa bit is 1, then the number is subnormal.
+
+  If all exponent bits are 1 and all mantissa bits are 0, 
+  then the number is infinity.
+
+  If all exponent bits are 1 and at least one mantissa bit is 1,
+  then the number is a not-a-number.
+
+  Otherwise the number is normal.
+
+(Note that the binary representation of infinity
+has flag bit 0 for Motorola 68K extended double precision,
+and flag bit 1 for Intel extended double precision.)
+
+To get the bits, the four or eight most significant bytes are copied
+into an uint32_t or uint64_t and bit masks are applied.
+This covers all the exponent bits and the flag bit (if there is one),
+but not always all the mantissa bits.
+Some of the functions below have two implementations,
+depending on whether all the mantissa bits are copied or not.
+*/
+
+#include <cmath>
+
+#ifndef FP_INFINITE
+#   define FP_INFINITE 0
+#   define FP_NAN 1
+#   define FP_NORMAL 2
+#   define FP_SUBNORMAL 3
+#   define FP_ZERO 4
+#endif
+
+#include "detail/fp_traits.hpp"
+
+namespace boost {
+namespace math {
+    
+//------------------------------------------------------------------------------
+
+template<class T> bool (isfinite)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+
+    BOOST_DEDUCED_TYPENAME traits::bits a;
+    traits::get_bits(x,a);
+    a &= traits::exponent;
+    return a != traits::exponent;
+}
+
+//------------------------------------------------------------------------------
+
+template<class T> bool (isnormal)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+
+    BOOST_DEDUCED_TYPENAME traits::bits a;
+    traits::get_bits(x,a);
+    a &= traits::exponent | traits::flag;
+    return (a != 0) && (a < traits::exponent);
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+    template<class T> bool isinf_impl(T x, all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+        a &= traits::exponent | traits::mantissa;
+        return a == traits::exponent;
+    }
+
+    template<class T> bool isinf_impl(T x, not_all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+        a &= traits::exponent | traits::mantissa;
+        if(a != traits::exponent)
+            return false;
+
+        traits::set_bits(x,0);
+        return x == 0;
+    }
+
+}   // namespace detail
+
+template<class T> bool (isinf)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+    return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+    template<class T> bool isnan_impl(T x, all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+        traits::init();
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+        a &= traits::exponent | traits::mantissa;
+        return a > traits::exponent;
+    }
+
+    template<class T> bool isnan_impl(T x, not_all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+        traits::init();
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+
+        a &= traits::exponent | traits::mantissa;
+        if(a < traits::exponent)
+            return false;
+
+        a &= traits::mantissa;
+        traits::set_bits(x,a);
+        return x != 0;
+    }
+
+}   // namespace detail
+
+template<class T> bool (isnan)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+    return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+    template<class T> int fpclassify_impl(T x, all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+        a &= traits::exponent | traits::flag | traits::mantissa;
+
+        if(a <= traits::mantissa) {
+            if(a == 0)
+                return FP_ZERO;
+            else
+                return FP_SUBNORMAL;
+        }
+
+        if(a < traits::exponent)
+            return FP_NORMAL;
+
+        a &= traits::mantissa;
+        if(a == 0)
+            return FP_INFINITE;
+
+        return FP_NAN;
+    }
+
+    template<class T> int fpclassify_impl(T x, not_all_bits)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a); 
+        a &= traits::exponent | traits::flag | traits::mantissa;
+
+        if(a <= traits::mantissa) {
+            if(x == 0)
+                return FP_ZERO;
+            else
+                return FP_SUBNORMAL;
+        }
+            
+        if(a < traits::exponent)
+            return FP_NORMAL;
+
+        a &= traits::mantissa;
+        traits::set_bits(x,a);
+        if(x == 0)
+            return FP_INFINITE;
+        
+        return FP_NAN;
+    }
+
+}   // namespace detail
+
+template<class T> int (fpclassify)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+    return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
+}
+
+//------------------------------------------------------------------------------
+
+}   // namespace math
+}   // namespace boost
+
+#endif
Added: trunk/boost/spirit/home/support/detail/math/nonfinite_num_facets.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/math/nonfinite_num_facets.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,475 @@
+#ifndef BOOST_MATH_NONFINITE_NUM_FACETS_HPP
+#define BOOST_MATH_NONFINITE_NUM_FACETS_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cstring>
+#include <ios>
+#include <limits>
+#include <locale>
+#include "fpclassify.hpp"
+#include "signbit.hpp"
+
+#ifdef _MSC_VER
+#   pragma warning(push)
+#   pragma warning(disable : 4127 4511 4512 4706)
+#endif
+
+namespace boost {
+namespace math {
+
+
+// flags -----------------------------------------------------------------------
+
+const int legacy = 0x1;
+const int signed_zero = 0x2;
+const int trap_infinity = 0x4;
+const int trap_nan = 0x8;
+
+
+// class nonfinite_num_put -----------------------------------------------------
+
+template<
+    class CharType, 
+    class OutputIterator = std::ostreambuf_iterator<CharType> 
+>
+class nonfinite_num_put : public std::num_put<CharType, OutputIterator> {
+public:
+    explicit nonfinite_num_put(int flags = 0) : flags_(flags) {}
+
+protected:
+    virtual OutputIterator do_put(
+        OutputIterator it, std::ios_base& iosb,
+        CharType fill, double val) const
+    {
+        put_and_reset_width(it, iosb, fill, val);
+        return it;
+    }
+
+    virtual OutputIterator do_put(
+        OutputIterator it, std::ios_base& iosb,
+        CharType fill, long double val) const
+    {
+        put_and_reset_width(it, iosb, fill, val);
+        return it;
+    }
+
+private:
+    template<class ValType> void put_and_reset_width(
+        OutputIterator& it, std::ios_base& iosb,
+        CharType fill, ValType val) const
+    {
+        put_impl(it, iosb, fill, val);
+        iosb.width(0);
+    }
+
+    template<class ValType> void put_impl(
+        OutputIterator& it, std::ios_base& iosb,
+        CharType fill, ValType val) const
+    {
+        switch((boost::math::fpclassify)(val)) {
+
+            case FP_INFINITE:
+                if(flags_ & trap_infinity)
+                    throw std::ios_base::failure("Infinity");
+                else if((boost::math::signbit)(val))
+                    put_num_and_fill(it, iosb, "-", "inf", fill);
+                else if(iosb.flags() & std::ios_base::showpos)
+                    put_num_and_fill(it, iosb, "+", "inf", fill);
+                else
+                    put_num_and_fill(it, iosb, "", "inf", fill);
+                break;
+            
+            case FP_NAN:
+                if(flags_ & trap_nan)
+                    throw std::ios_base::failure("NaN");
+                else if((boost::math::signbit)(val))
+                    put_num_and_fill(it, iosb, "-", "nan", fill);
+                else if(iosb.flags() & std::ios_base::showpos)
+                    put_num_and_fill(it, iosb, "+", "nan", fill);
+                else
+                    put_num_and_fill(it, iosb, "", "nan", fill);
+                break;
+
+            case FP_ZERO:
+                if(flags_ & signed_zero) {
+                    if((boost::math::signbit)(val))
+                        put_num_and_fill(it, iosb, "-", "0", fill);
+                    else if(iosb.flags() & std::ios_base::showpos)
+                        put_num_and_fill(it, iosb, "+", "0", fill);
+                    else
+                        put_num_and_fill(it, iosb, "", "0", fill);
+                }
+                else
+                    put_num_and_fill(it, iosb, "", "0", fill);
+                break;
+
+            default:
+                it = std::num_put<CharType, OutputIterator>::do_put(
+                    it, iosb, fill, val);
+                break;
+        }
+    }
+
+    void put_num_and_fill(
+        OutputIterator& it, std::ios_base& iosb, const char* prefix,
+        const char* body, CharType fill) const
+    {
+        int width = (int)strlen(prefix) + (int)strlen(body);
+        std::ios_base::fmtflags adjust
+            = iosb.flags() & std::ios_base::adjustfield;
+        const std::ctype<CharType>& ct
+            = std::use_facet<std::ctype<CharType> >(iosb.getloc());
+
+        if(adjust != std::ios_base::internal && adjust != std::ios_base::left)
+            put_fill(it, iosb, fill, width);
+
+        while(*prefix)
+            *it = ct.widen(*(prefix++));
+
+        if(adjust == std::ios_base::internal)
+            put_fill(it, iosb, fill, width);
+
+        if(iosb.flags() & std::ios_base::uppercase) {
+            while(*body)
+                *it = ct.toupper(ct.widen(*(body++)));
+        }
+        else {
+            while(*body)
+                *it = ct.widen(*(body++));
+        }
+
+        if(adjust == std::ios_base::left)
+            put_fill(it, iosb, fill, width);
+    }
+
+    void put_fill(
+        OutputIterator& it, std::ios_base& iosb, 
+        CharType fill, int width) const
+    {
+        for(int i = iosb.width() - width; i > 0; --i)
+            *it = fill;
+    }
+
+private:
+    const int flags_;
+};
+
+
+// class nonfinite_num_get ------------------------------------------------------
+
+template<
+    class CharType, 
+    class InputIterator = std::istreambuf_iterator<CharType> 
+>
+class nonfinite_num_get : public std::num_get<CharType, InputIterator> {
+public:
+    explicit nonfinite_num_get(int flags = 0) : flags_(flags) {}
+
+protected:
+    virtual InputIterator do_get(
+        InputIterator it, InputIterator end, std::ios_base& iosb,
+        std::ios_base::iostate& state, float& val) const
+    {
+        get_and_check_eof(it, end, iosb, state, val);
+        return it;
+    }
+
+    virtual InputIterator do_get(
+        InputIterator it, InputIterator end, std::ios_base& iosb,
+        std::ios_base::iostate& state, double& val) const
+    {
+        get_and_check_eof(it, end, iosb, state, val);
+        return it;
+    }
+
+    virtual InputIterator do_get(
+        InputIterator it, InputIterator end, std::ios_base& iosb,
+        std::ios_base::iostate& state, long double& val) const
+    {
+        get_and_check_eof(it, end, iosb, state, val);
+        return it;
+    }
+
+//..............................................................................
+    
+private:
+    template<class ValType> static ValType positive_nan()
+    {
+        // on some platforms quiet_NaN() is negative
+        return (boost::math::copysign)(
+            std::numeric_limits<ValType>::quiet_NaN(), 1);  
+    }
+
+    template<class ValType> void get_and_check_eof(
+        InputIterator& it, InputIterator end, std::ios_base& iosb,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        get_signed(it, end, iosb, state, val);
+        if(it == end)
+            state |= std::ios_base::eofbit;
+    }
+
+    template<class ValType> void get_signed(
+        InputIterator& it, InputIterator end, std::ios_base& iosb,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        const std::ctype<CharType>& ct
+            = std::use_facet<std::ctype<CharType> >(iosb.getloc());
+
+        char c = peek_char(it, end, ct);
+
+        bool negative = (c == '-');
+
+        if(negative || c == '+') {
+            ++it;
+            c = peek_char(it, end, ct);
+            if(c == '-' || c == '+') {
+                // without this check, "++5" etc would be accepted
+                state |= std::ios_base::failbit;
+                return;
+            }
+        }
+
+        get_unsigned(it, end, iosb, ct, state, val);
+
+        if(negative)
+            val = (boost::math::changesign)(val);
+    }
+
+    template<class ValType> void get_unsigned(
+        InputIterator& it, InputIterator end, std::ios_base& iosb,
+        const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        switch(peek_char(it, end, ct)) {
+
+            case 'i': 
+                get_i(it, end, ct, state, val);
+                break;
+
+            case 'n':
+                get_n(it, end, ct, state, val);
+                break;
+
+            case 'q':
+            case 's':
+                get_q(it, end, ct, state, val);
+                break;
+
+            default:
+                it = std::num_get<CharType, InputIterator>::do_get(
+                        it, end, iosb, state, val);
+                if((flags_ & legacy) && val == static_cast<ValType>(1)
+                        && peek_char(it, end, ct) == '#')
+                    get_one_hash(it, end, ct, state, val);
+                break;
+        }
+    }
+
+    //..........................................................................
+
+    template<class ValType> void get_i(
+        InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        if(!std::numeric_limits<ValType>::has_infinity
+                || (flags_ & trap_infinity)) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        ++it;
+
+        if(!match_string(it, end, ct, "nf")) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        if(peek_char(it, end, ct) != 'i') {
+            val = std::numeric_limits<ValType>::infinity();     // "inf"
+            return;
+        }
+
+        ++it;
+
+        if(!match_string(it, end, ct, "nity")) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        val = std::numeric_limits<ValType>::infinity();         // "infinity"
+    }
+
+    template<class ValType> void get_n(
+        InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        if(!std::numeric_limits<ValType>::has_quiet_NaN 
+                || (flags_ & trap_nan)) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        ++it;
+            
+        if(!match_string(it, end, ct, "an")) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        switch(peek_char(it, end, ct)) {
+            case 'q':
+            case 's':
+                if(flags_ && legacy)
+                    ++it;
+                break;              // "nanq", "nans"
+                
+            case '(': 
+            {
+                ++it;
+                char c;
+                while((c = peek_char(it, end, ct))
+                        && c != ')' && c != ' ' && c != '\n' && c != '\t')
+                    ++it;
+                if(c != ')') {
+                    state |= std::ios_base::failbit;
+                    return;
+                }
+                ++it;           
+                break;              // "nan(...)"
+            }
+
+            default:
+                break;              // "nan"
+        }
+
+        val = positive_nan<ValType>();
+    }
+
+    template<class ValType> void get_q(
+        InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        if(!std::numeric_limits<ValType>::has_quiet_NaN 
+                || (flags_ & trap_nan) || !(flags_ & legacy)) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        ++it;
+
+        if(!match_string(it, end, ct, "nan")) {
+            state |= std::ios_base::failbit;
+            return;
+        }
+
+        val = positive_nan<ValType>();      // qnan, snan
+    }
+
+    template<class ValType> void get_one_hash(
+        InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        ++it;
+
+        switch(peek_char(it, end, ct)) {
+            case 'i':
+                get_one_hash_i(it, end, ct, state, val);
+                return;
+
+            case 'q':
+            case 's':
+                if(std::numeric_limits<ValType>::has_quiet_NaN
+                        && !(flags_ & trap_nan)) {
+                    ++it;
+                    if(match_string(it, end, ct, "nan")) {  
+                                                        // "1.#QNAN", "1.#SNAN"
+                        ++it;
+                        val = positive_nan<ValType>();
+                        return;
+                    }
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        state |= std::ios_base::failbit;
+    }
+   
+    template<class ValType> void get_one_hash_i(
+        InputIterator& it, InputIterator end, const std::ctype<CharType>& ct,
+        std::ios_base::iostate& state, ValType& val) const
+    {
+        ++it;
+
+        if(peek_char(it, end, ct) == 'n') {
+            ++it;
+            switch(peek_char(it, end, ct)) {
+                case 'f':                                       // "1.#INF"
+                    if(std::numeric_limits<ValType>::has_infinity
+                            && !(flags_ & trap_infinity)) {
+                        ++it;
+                        val = std::numeric_limits<ValType>::infinity(); 
+                        return;
+                    }
+                    break;
+
+                case 'd':                                       // 1.#IND"
+                    if(std::numeric_limits<ValType>::has_quiet_NaN
+                            && !(flags_ & trap_nan)) {
+                        ++it;
+                        val = positive_nan<ValType>();
+                        return;
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        state |= std::ios_base::failbit;
+    }
+
+    //..........................................................................
+
+    char peek_char(
+        InputIterator& it, InputIterator end, 
+        const std::ctype<CharType>& ct) const
+    {
+        if(it == end) return 0;
+        return ct.narrow(ct.tolower(*it), 0);
+    }
+
+    bool match_string(
+        InputIterator& it, InputIterator end,
+        const std::ctype<CharType>& ct, const char* s) const
+    {
+        while(it != end && *s && *s == ct.narrow(ct.tolower(*it), 0)) {
+            ++s;
+            ++it;
+        }
+        return !*s;
+    }
+
+private:
+    const int flags_;
+};
+
+//------------------------------------------------------------------------------
+
+}   // namespace serialization
+}   // namespace boost
+
+#ifdef _MSC_VER
+#   pragma warning(pop)
+#endif
+
+#endif
Added: trunk/boost/spirit/home/support/detail/math/signbit.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/math/signbit.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,86 @@
+// signbit.hpp
+
+#ifndef BOOST_MATH_SIGNBIT_HPP
+#define BOOST_MATH_SIGNBIT_HPP
+
+// Copyright (c) 2006 Johan Rade
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "detail/fp_traits.hpp"
+
+namespace boost {
+namespace math {
+
+//------------------------------------------------------------------------------
+
+template<class T> bool (signbit)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+
+    BOOST_DEDUCED_TYPENAME traits::bits a;
+    traits::get_bits(x,a);
+    a &= traits::sign;
+    return a != 0;
+}
+
+//------------------------------------------------------------------------------
+
+namespace detail {
+
+    template<class T> T copysign_impl(T x, T y)
+    {
+        typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
+        traits::init();
+
+        BOOST_DEDUCED_TYPENAME traits::bits a;
+        traits::get_bits(x,a);
+        a &= ~traits::sign;
+
+        BOOST_DEDUCED_TYPENAME traits::bits b;
+        traits::get_bits(y,b);
+        b &= traits::sign;
+
+        traits::set_bits(x,a|b);
+        return x;
+    }
+}
+
+inline float (copysign)(float x, float y)      // magnitude of x and sign of y
+{
+    return detail::copysign_impl(x,y);
+}
+
+inline double (copysign)(double x, double y)
+{
+    return detail::copysign_impl(x,y);
+}
+
+inline long double (copysign)(long double x, long double y)
+{
+    return detail::copysign_impl(x,y);
+}
+
+//------------------------------------------------------------------------------
+
+template<class T> T (changesign)(T x)
+{
+    typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
+    traits::init();
+
+    BOOST_DEDUCED_TYPENAME traits::bits a;
+    traits::get_bits(x,a);
+    a ^= traits::sign;
+    traits::set_bits(x,a);
+    return x;
+}
+
+//------------------------------------------------------------------------------
+
+}   // namespace math
+}   // namespace boost
+
+#endif
Added: trunk/boost/spirit/home/support/detail/to_narrow.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/to_narrow.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_TO_NARROW_APRIL_29_2007_1122AM)
+#define BOOST_SPIRIT_TO_NARROW_APRIL_29_2007_1122AM
+
+#include <string>
+#include <locale>
+#include <memory>
+
+namespace boost { namespace spirit { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    inline char to_narrow_char(Char ch)
+    {
+        typedef std::ctype<Char> ctype_type;
+        return std::use_facet<ctype_type>(std::locale()).narrow(ch, '.');
+    }
+
+    inline char to_narrow_char(char ch)
+    {
+        return ch;
+    }
+
+    template <typename Char>
+    inline std::size_t getlength(Char const* p)
+    {
+        std::size_t len = 0;
+        while (*p)
+            ++len, ++p;
+        return len;
+    }
+
+    template <typename Char>
+    inline std::string to_narrow_string(Char const* source)
+    {
+        typedef std::ctype<Char> ctype_type;
+
+        std::size_t len = getlength(source);
+        std::auto_ptr<char> buffer(new char [len+1]);
+        std::use_facet<ctype_type>(std::locale())
+            .narrow(source, source + len, '.', buffer.get());
+
+        return std::string(buffer.get(), len);
+    }
+
+    inline std::string to_narrow_string(char const* source)
+    {
+        return source;
+    }
+
+    template <typename Char>
+    inline std::string to_narrow_string(std::basic_string<Char> const& str)
+    {
+        return to_narrow_string(str.c_str());
+    }
+
+    inline std::string const& to_narrow_string(std::string const& str)
+    {
+        return str;
+    }
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/unordered/detail/allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/unordered/detail/allocator.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,231 @@
+
+// Copyright 2005 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
+#define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
+    && !defined(__BORLANDC__)
+#  define BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
+#endif
+
+#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
+#  include <boost/detail/allocator_utilities.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost {
+    namespace unordered_detail {
+
+#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
+        template <class Alloc, class T>
+        struct rebind_wrap : ::boost::detail::allocator::rebind_to<Alloc, T> {};
+#else
+        template <class Alloc, class T>
+        struct rebind_wrap
+        {
+            typedef BOOST_DEDUCED_TYPENAME
+                Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
+                type;
+        };
+#endif
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+        template <class T>
+        inline void reset(T& x) { x  = T(); }
+#else
+        template <class T>
+        inline void reset_impl(T& x, ...) { x  = T(); }
+        template <class T>
+        inline void reset_impl(T*& x, int) { x  = 0; }
+        template <class T>
+        inline void reset(T& x) { reset_impl(x); }
+#endif
+
+        // Work around for Microsoft's ETI bug.
+        
+        template <class Allocator> struct allocator_value_type
+        {
+            typedef typename Allocator::value_type type;
+        };
+
+        template <class Allocator> struct allocator_pointer
+        {
+            typedef typename Allocator::pointer type;
+        };
+        
+        template <class Allocator> struct allocator_const_pointer
+        {
+            typedef typename Allocator::const_pointer type;
+        };
+        
+        template <class Allocator> struct allocator_reference
+        {
+            typedef typename Allocator::reference type;
+        };
+        
+        template <class Allocator> struct allocator_const_reference
+        {
+            typedef typename Allocator::const_reference type;
+        };
+        
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+
+        template <>
+        struct allocator_value_type<int>
+        {
+            typedef int type;
+        };
+
+        template <>
+        struct allocator_pointer<int>
+        {
+            typedef int type;
+        };
+
+        template <>
+        struct allocator_const_pointer<int>
+        {
+            typedef int type;
+        };
+
+        template <>
+        struct allocator_reference<int>
+        {
+            typedef int type;
+        };
+
+        template <>
+        struct allocator_const_reference<int>
+        {
+            typedef int type;
+        };
+
+#endif
+
+        template <class Allocator>
+        struct allocator_constructor
+        {
+            typedef typename Allocator::value_type value_type;
+            typedef typename allocator_pointer<Allocator>::type pointer;
+
+            Allocator& alloc_;
+            pointer ptr_;
+            bool constructed_;
+
+            allocator_constructor(Allocator& a)
+                : alloc_(a), ptr_(), constructed_(false)
+            {
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+                    unordered_detail::reset(ptr_);
+#endif
+            }
+
+            ~allocator_constructor() {
+                if(ptr_) {
+                    if(constructed_) alloc_.destroy(ptr_);
+                    alloc_.deallocate(ptr_, 1);
+                }
+            }
+
+            template <class V>
+            void construct(V const& v) {
+                BOOST_ASSERT(!ptr_ && !constructed_);
+                ptr_ = alloc_.allocate(1);
+                alloc_.construct(ptr_, value_type(v));
+                constructed_  = true;
+            }
+
+            void construct(value_type const& v) {
+                BOOST_ASSERT(!ptr_ && !constructed_);
+                ptr_ = alloc_.allocate(1);
+                alloc_.construct(ptr_, v);
+                constructed_  = true;
+            }
+
+            pointer get() const
+            {
+                return ptr_;
+            }
+
+            // no throw
+            pointer release()
+            {
+                pointer p = ptr_;
+                constructed_ = false;
+                reset(ptr_);
+                return p;
+            }
+        };
+
+        template <class Allocator>
+        struct allocator_array_constructor
+        {
+            typedef typename allocator_pointer<Allocator>::type pointer;
+
+            Allocator& alloc_;
+            pointer ptr_;
+            pointer constructed_;
+            std::size_t length_;
+
+            allocator_array_constructor(Allocator& a)
+                : alloc_(a), ptr_(), constructed_(), length_(0)
+            {
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+                unordered_detail::reset(constructed_);
+                unordered_detail::reset(ptr_);
+#endif
+            }
+
+            ~allocator_array_constructor() {
+                if (ptr_) {
+                    for(pointer p = ptr_; p != constructed_; ++p)
+                        alloc_.destroy(p);
+
+                    alloc_.deallocate(ptr_, length_);
+                }
+            }
+
+            template <class V>
+            void construct(V const& v, std::size_t l)
+            {
+                BOOST_ASSERT(!ptr_);
+                length_ = l;
+                ptr_ = alloc_.allocate(length_);
+                pointer end = ptr_ + length_;
+                for(constructed_ = ptr_; constructed_ != end; ++constructed_)
+                    alloc_.construct(constructed_, v);
+            }
+
+            pointer get() const
+            {
+                return ptr_;
+            }
+
+            pointer release()
+            {
+                pointer p(ptr_);
+                reset(ptr_);
+                return p;
+            }
+        private:
+            allocator_array_constructor(allocator_array_constructor const&);
+            allocator_array_constructor& operator=(allocator_array_constructor const&);
+        };
+    }
+}
+
+#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
+#  undef BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
+#endif
+
+#endif
Added: trunk/boost/spirit/home/support/detail/unordered/detail/hash_table.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/unordered/detail/hash_table.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,191 @@
+
+// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
+// Copyright (C) 2005-2006 Daniel James
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UNORDERED_DETAIL_HASH_TABLE_HPP_INCLUDED
+#define BOOST_UNORDERED_DETAIL_HASH_TABLE_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#define BOOST_UNORDERED_PARANOID
+
+#include <boost/config.hpp>
+
+#include <cstddef>
+#include <cmath>
+#include <algorithm>
+#include <utility>
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/limits.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/spirit/home/support/detail/unordered/detail/allocator.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/mpl/aux_/config/eti.hpp>
+
+// See hash_table::swap() for details about this.
+#if !defined(BOOST_UNORDERED_SWAP_METHOD)
+#define BOOST_UNORDERED_SWAP_METHOD 3
+#endif
+
+#if BOOST_UNORDERED_SWAP_METHOD == 1
+#include <stdexcept>
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
+#define BOOST_HASH_BORLAND_BOOL(x) (bool)(x)
+#else
+#define BOOST_HASH_BORLAND_BOOL(x) x
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#define BOOST_HASH_MSVC_RESET_PTR(x) unordered_detail::reset(x)
+#else
+#define BOOST_HASH_MSVC_RESET_PTR(x)
+#endif
+
+namespace boost {
+    namespace unordered_detail {
+        template <class T> struct type_wrapper {};
+
+        const static std::size_t default_initial_bucket_count = 50;
+        const static float minimum_max_load_factor = 1e-3f;
+        inline std::size_t next_prime(std::size_t n);
+
+        template <class T>
+        inline void hash_swap(T& x, T& y)
+        {
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+            std::swap(x,y);
+#else
+            using std::swap;
+            swap(x, y);
+#endif
+        }
+
+        inline std::size_t float_to_size_t(float f)
+        {
+            return f > static_cast<float>((std::numeric_limits<std::size_t>::max)()) ?
+                (std::numeric_limits<std::size_t>::max)() :
+                static_cast<std::size_t>(f);
+        }
+
+        // prime number list, accessor
+
+        static const std::size_t prime_list[] = {
+            53ul, 97ul, 193ul, 389ul, 769ul,
+            1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
+            49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
+            1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
+            50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
+            1610612741ul, 3221225473ul, 4294967291ul };
+
+        // no throw
+        inline std::size_t next_prime(std::size_t n) {
+            std::size_t const* bound =
+                std::lower_bound(prime_list,prime_list + 28, n);
+            if(bound == prime_list + 28)
+                bound--;
+            return *bound;
+        }
+
+        // no throw
+        inline std::size_t prev_prime(std::size_t n) {
+            std::size_t const* bound =
+                std::upper_bound(prime_list,prime_list + 28, n);
+            if(bound != prime_list)
+                bound--;
+            return *bound;
+        }
+
+        // pair_cast - used to convert between pair types.
+
+        template <class Dst1, class Dst2, class Src1, class Src2>
+        inline std::pair<Dst1, Dst2> pair_cast(std::pair<Src1, Src2> const& x)
+        {
+            return std::pair<Dst1, Dst2>(Dst1(x.first), Dst2(x.second));
+        }
+    }
+}
+
+#define BOOST_UNORDERED_HASH_EQUIVALENT 1
+#include <boost/spirit/home/support/detail/unordered/detail/hash_table_impl.hpp>
+#undef BOOST_UNORDERED_HASH_EQUIVALENT
+
+#define BOOST_UNORDERED_HASH_EQUIVALENT 0
+#include <boost/spirit/home/support/detail/unordered/detail/hash_table_impl.hpp>
+#undef BOOST_UNORDERED_HASH_EQUIVALENT
+
+namespace boost {
+    namespace unordered_detail {
+        class iterator_access
+        {
+        public:
+            template <class Iterator>
+            static BOOST_DEDUCED_TYPENAME Iterator::base const& get(Iterator const& it) {
+                return it.base_;
+            }
+        };
+
+        template <class ValueType, class KeyType,
+            class Hash, class Pred, class Alloc>
+        class hash_types_unique_keys
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME
+                boost::unordered_detail::rebind_wrap<Alloc, ValueType>::type
+                value_allocator;
+
+            typedef hash_table_unique_keys<ValueType, KeyType, Hash, Pred,
+                    value_allocator> hash_table;
+            typedef hash_table_data_unique_keys<value_allocator> data;
+            typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
+
+            typedef hash_const_local_iterator_unique_keys<value_allocator> const_local_iterator;
+            typedef hash_local_iterator_unique_keys<value_allocator> local_iterator;
+            typedef hash_const_iterator_unique_keys<value_allocator> const_iterator;
+            typedef hash_iterator_unique_keys<value_allocator> iterator;
+
+            typedef BOOST_DEDUCED_TYPENAME data::size_type size_type;
+            typedef std::ptrdiff_t difference_type;
+        };
+
+        template <class ValueType, class KeyType,
+            class Hash, class Pred, class Alloc>
+        class hash_types_equivalent_keys
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME
+                boost::unordered_detail::rebind_wrap<Alloc, ValueType>::type
+                value_allocator;
+
+            typedef hash_table_equivalent_keys<ValueType, KeyType, Hash, Pred,
+                    value_allocator> hash_table;
+            typedef hash_table_data_equivalent_keys<value_allocator> data;
+            typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
+
+            typedef hash_const_local_iterator_equivalent_keys<value_allocator> const_local_iterator;
+            typedef hash_local_iterator_equivalent_keys<value_allocator> local_iterator;
+            typedef hash_const_iterator_equivalent_keys<value_allocator> const_iterator;
+            typedef hash_iterator_equivalent_keys<value_allocator> iterator;
+
+            typedef BOOST_DEDUCED_TYPENAME data::size_type size_type;
+            typedef std::ptrdiff_t difference_type;
+        };
+    } // namespace boost::unordered_detail
+} // namespace boost
+
+#undef BOOST_HASH_BORLAND_BOOL
+#undef BOOST_HASH_MSVC_RESET_PTR
+
+#endif // BOOST_UNORDERED_DETAIL_HASH_TABLE_HPP_INCLUDED
Added: trunk/boost/spirit/home/support/detail/unordered/detail/hash_table_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/unordered/detail/hash_table_impl.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,2092 @@
+
+// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
+// Copyright (C) 2005-2006 Daniel James
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+#define HASH_TABLE hash_table_equivalent_keys
+#define HASH_TABLE_DATA hash_table_data_equivalent_keys
+#define HASH_ITERATOR hash_iterator_equivalent_keys
+#define HASH_CONST_ITERATOR hash_const_iterator_equivalent_keys
+#define HASH_LOCAL_ITERATOR hash_local_iterator_equivalent_keys
+#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys
+#else
+#define HASH_TABLE hash_table_unique_keys
+#define HASH_TABLE_DATA hash_table_data_unique_keys
+#define HASH_ITERATOR hash_iterator_unique_keys
+#define HASH_CONST_ITERATOR hash_const_iterator_unique_keys
+#define HASH_LOCAL_ITERATOR hash_local_iterator_unique_keys
+#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_unique_keys
+#endif
+
+namespace boost {
+    namespace unordered_detail {
+
+        //
+        // Hash Table Data
+        //
+        // Responsible for managing the hash buckets.
+
+        template <class Alloc>
+        class HASH_TABLE_DATA
+        {
+        public:
+            class node;
+            class node_links;
+            class bucket;
+            typedef std::size_t size_type;
+
+            typedef Alloc value_allocator;
+
+            typedef BOOST_DEDUCED_TYPENAME
+                boost::unordered_detail::rebind_wrap<Alloc, node>::type
+                node_allocator;
+            typedef BOOST_DEDUCED_TYPENAME
+                boost::unordered_detail::rebind_wrap<Alloc, node_links>::type
+                node_links_allocator;
+            typedef BOOST_DEDUCED_TYPENAME
+                boost::unordered_detail::rebind_wrap<Alloc, bucket>::type
+                bucket_allocator;
+
+            typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
+            typedef BOOST_DEDUCED_TYPENAME allocator_pointer<node_allocator>::type node_ptr;
+            typedef BOOST_DEDUCED_TYPENAME allocator_pointer<bucket_allocator>::type bucket_ptr;
+            typedef BOOST_DEDUCED_TYPENAME allocator_reference<value_allocator>::type reference;
+
+            // Hash Bucket
+            //
+            // all no throw
+
+            class bucket
+            {
+                bucket& operator=(bucket const&);
+            public:
+                node_ptr first_;
+
+                bucket() : first_()
+                {
+                    BOOST_HASH_MSVC_RESET_PTR(first_);
+                }
+
+                bucket(bucket const& x) : first_(x.first_)
+                {
+                    // Only copy construct when allocating.
+                    BOOST_ASSERT(!x.first_);
+                }
+
+                bool empty() const
+                {
+                    return !this->first_;
+                }
+            };
+
+            // Hash Node
+            //
+            // all no throw
+
+            class node_links
+            {
+            public:
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+                node_links() : next_(), group_prev_()
+                {
+                    BOOST_HASH_MSVC_RESET_PTR(next_);
+                    BOOST_HASH_MSVC_RESET_PTR(group_prev_);
+                }
+
+                node_ptr next_;
+                node_ptr group_prev_;
+#else
+                node_links() : next_()
+                {
+                    BOOST_HASH_MSVC_RESET_PTR(next_);
+                }
+
+                node_ptr next_;
+#endif
+            };
+
+            struct node
+            {
+                node_links links_;
+                value_type value_;
+            };
+
+            // node_constructor
+            //
+            // Used to construct nodes in an exception safe manner.
+
+            struct allocators
+            {
+                node_allocator node_alloc_;
+                bucket_allocator bucket_alloc_;
+                value_allocator value_alloc_;
+                node_links_allocator node_links_alloc_;
+
+                allocators(value_allocator const& a)
+                    : node_alloc_(a), bucket_alloc_(a),
+                    value_alloc_(a), node_links_alloc_(a)
+                {}
+
+                void destroy(node_ptr n)
+                {
+                    value_alloc_.destroy(value_alloc_.address(n->value_));
+                    node_links_alloc_.destroy(node_links_alloc_.address(n->links_));
+                    node_alloc_.deallocate(n, 1);
+                }
+
+                void swap(allocators& x)
+                {
+                    hash_swap(node_alloc_, x.node_alloc_);
+                    hash_swap(bucket_alloc_, x.bucket_alloc_);
+                    hash_swap(value_alloc_, x.value_alloc_);
+                    hash_swap(node_links_alloc_, x.node_links_alloc_);
+                }
+
+                bool operator==(allocators const& x)
+                {
+                    return value_alloc_ == x.value_alloc_;
+                }
+            };
+
+            class node_constructor
+            {
+                allocators& allocators_;
+
+                node_ptr node_;
+                bool value_constructed_;
+                bool node_links_constructed_;
+
+            public:
+
+                node_constructor(allocators& a)
+                    : allocators_(a),
+                    node_(), value_constructed_(false), node_links_constructed_(false)
+                {
+                    BOOST_HASH_MSVC_RESET_PTR(node_);
+                }
+
+                ~node_constructor()
+                {
+                    if (node_) {
+                        if (value_constructed_)
+                            allocators_.value_alloc_.destroy(
+                                allocators_.value_alloc_.address(node_->value_));
+                        if (node_links_constructed_)
+                            allocators_.node_links_alloc_.destroy(
+                                allocators_.node_links_alloc_.address(node_->links_));
+
+                        allocators_.node_alloc_.deallocate(node_, 1);
+                    }
+                }
+
+                template <class V>
+                void construct(V const& v)
+                {
+                    BOOST_ASSERT(!node_);
+                    value_constructed_ = node_links_constructed_ = false;
+
+                    node_ = allocators_.node_alloc_.allocate(1);
+
+                    allocators_.node_links_alloc_.construct(
+                            allocators_.node_links_alloc_.address(node_->links_),
+                            node_links());
+                    node_links_constructed_ = true;
+
+                    allocators_.value_alloc_.construct(
+                            allocators_.value_alloc_.address(node_->value_), v);
+                    value_constructed_ = true;
+                }
+
+                node_ptr get() const
+                {
+                    BOOST_ASSERT(node_);
+                    return node_;
+                }
+
+                // no throw
+                node_ptr release()
+                {
+                    node_ptr n = node_;
+                    unordered_detail::reset(node_);
+                    return n;
+                }
+
+            private:
+                node_constructor(node_constructor const&);
+                node_constructor& operator=(node_constructor const&);
+            };
+
+            // Methods for navigating groups of elements with equal keys.
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            static node_ptr& prev_in_group(node_ptr n) {
+                return n->links_.group_prev_;
+            }
+
+            // pre: Must be pointing to the first node in a group.
+            static node_ptr last_in_group(node_ptr n) {
+                BOOST_ASSERT(n && n != prev_in_group(n)->links_.next_);
+                return prev_in_group(n);
+            }
+
+            // pre: Must be pointing to the first node in a group.
+            static node_ptr& next_group(node_ptr n) {
+                BOOST_ASSERT(n && n != prev_in_group(n)->links_.next_);
+                return prev_in_group(n)->links_.next_;
+            }
+#else
+            static node_ptr last_in_group(node_ptr n) {
+                return n;
+            }
+
+            static node_ptr& next_group(node_ptr n) {
+                BOOST_ASSERT(n);
+                return n->links_.next_;
+            }
+#endif
+
+            class local_iterator_base
+            {
+            public:
+                node_ptr node_;
+
+                local_iterator_base()
+                    : node_()
+                {
+                    BOOST_HASH_MSVC_RESET_PTR(node_);
+                }
+
+                explicit local_iterator_base(node_ptr n)
+                    : node_(n) {}
+
+                bool not_finished() const
+                {
+                    return node_ ? true : false;
+                }
+
+                bool operator==(local_iterator_base const& x) const
+                {
+                    return node_ == x.node_;
+                }
+
+                bool operator!=(local_iterator_base const& x) const
+                {
+                    return node_ != x.node_;
+                }
+
+                reference operator*() const
+                {
+                    return node_->value_;
+                }
+
+                void increment()
+                {
+                    BOOST_ASSERT(node_);
+                    node_ = node_->links_.next_;
+                }
+
+                void next_group()
+                {
+                    node_ = HASH_TABLE_DATA::next_group(node_);
+                }
+            };
+
+            class iterator_base
+            {
+            public:
+                bucket_ptr bucket_;
+                local_iterator_base local_;
+
+                iterator_base()
+                    : bucket_(), local_() {}
+
+                explicit iterator_base(bucket_ptr b)
+                    : bucket_(b), local_(b->first_) {}
+
+                iterator_base(bucket_ptr b, node_ptr n)
+                    : bucket_(b), local_(n) {}
+
+                iterator_base(bucket_ptr b, local_iterator_base const& it)
+                    : bucket_(b), local_(it) {}
+
+                bool operator==(iterator_base const& x) const
+                {
+                    return local_ == x.local_;
+                }
+
+                bool operator!=(iterator_base const& x) const
+                {
+                    return local_ != x.local_;
+                }
+
+                reference operator*() const
+                {
+                    return *local_;
+                }
+
+                void increment()
+                {
+                    BOOST_ASSERT(bucket_);
+                    local_.increment();
+
+                    if(!local_.node_) {
+                        do {
+                            ++bucket_;
+                        } while(!bucket_->first_);
+
+                        // If at the end of the buckets...
+                        if(bucket_->first_ == (bucket_ + 1)->first_)
+                            unordered_detail::reset(local_);
+                        else
+                            local_ = local_iterator_base(bucket_->first_);
+                    }
+                }
+            };
+
+            // Member Variables
+
+            allocators allocators_;
+            bucket_ptr buckets_;
+            size_type bucket_count_;
+            bucket_ptr cached_begin_bucket_;
+            size_type size_;
+
+            // Constructors/Deconstructor
+
+            HASH_TABLE_DATA(size_type n, value_allocator const& a)
+              : allocators_(a),
+                buckets_(), bucket_count_(next_prime(n)),
+                cached_begin_bucket_(), size_(0)
+            {
+                // The array constructor will clean up in the event of an
+                // exception.
+                allocator_array_constructor<bucket_allocator>
+                    constructor(allocators_.bucket_alloc_);
+
+                // Creates two extra buckets to act as sentinels.
+                constructor.construct(bucket(), bucket_count_ + 2);
+
+                cached_begin_bucket_ = constructor.get() + bucket_count_;
+
+                // Only release the buckets once everything is successfully
+                // done.
+                buckets_ = constructor.release();
+            }
+
+            HASH_TABLE_DATA(HASH_TABLE_DATA const& x, size_type n)
+              : allocators_(x.allocators_),
+                buckets_(), bucket_count_(next_prime(n)),
+                cached_begin_bucket_(), size_(0)
+            {
+                // The array constructor will clean up in the event of an
+                // exception.
+                allocator_array_constructor<bucket_allocator>
+                    constructor(allocators_.bucket_alloc_);
+
+                // Creates two extra buckets to act as sentinels.
+                constructor.construct(bucket(), bucket_count_ + 2);
+
+                cached_begin_bucket_ = constructor.get() + bucket_count_;
+
+                // Only release the buckets once everything is successfully
+                // done.
+                buckets_ = constructor.release();
+            }
+
+            // no throw
+            ~HASH_TABLE_DATA()
+            {
+                if(buckets_) {
+                    bucket_ptr begin = cached_begin_bucket_;
+                    bucket_ptr end = buckets_ + bucket_count_;
+                    while(begin != end) {
+                        clear_bucket(begin);
+                        ++begin;
+                    }
+
+                    // Destroy two extra buckets for the sentinels.
+                    for(size_type i2 = 0; i2 < bucket_count_ + 2; ++i2)
+                        allocators_.bucket_alloc_.destroy(buckets_ + i2);
+
+                    allocators_.bucket_alloc_.deallocate(buckets_, bucket_count_ + 2);
+                }
+            }
+
+        private:
+
+            HASH_TABLE_DATA(HASH_TABLE_DATA const&);
+            HASH_TABLE_DATA& operator=(HASH_TABLE_DATA const&);
+
+        public:
+
+            // no throw
+            void swap(HASH_TABLE_DATA& other)
+            {
+                std::swap(buckets_, other.buckets_);
+                std::swap(bucket_count_, other.bucket_count_);
+                std::swap(cached_begin_bucket_, other.cached_begin_bucket_);
+                std::swap(size_, other.size_);
+            }
+
+            // Return the bucket index for a hashed value.
+            //
+            // no throw
+            size_type index_from_hash(size_type hashed) const
+            {
+                return hashed % bucket_count_;
+            }
+
+            // Begin & End
+            //
+            // no throw
+
+            iterator_base begin() const
+            {
+                return size_
+                    ? iterator_base(cached_begin_bucket_)
+                    : end();
+            }
+
+            iterator_base end() const
+            {
+                return iterator_base(buckets_ + bucket_count_, local_iterator_base());
+            }
+
+            local_iterator_base begin(size_type n) const
+            {
+                return local_iterator_base(buckets_[n].first_);
+            }
+
+            local_iterator_base end(size_type) const
+            {
+                return local_iterator_base();
+            }
+
+            local_iterator_base begin(bucket_ptr b) const
+            {
+                return local_iterator_base(b->first_);
+            }
+
+            // Bucket Size
+
+            // no throw
+            size_type node_count(local_iterator_base it) const
+            {
+                size_type count = 0;
+                while(it.not_finished()) {
+                    ++count;
+                    it.increment();
+                }
+                return count;
+            }
+
+            size_type node_count(local_iterator_base it1,
+                    local_iterator_base it2) const
+            {
+                size_type count = 0;
+                while(it1 != it2) {
+                    ++count;
+                    it1.increment();
+                }
+                return count;
+            }
+
+            size_type bucket_size(size_type n) const
+            {
+                return node_count(begin(n));
+            }
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            size_type group_count(local_iterator_base first_node) const
+            {
+                size_type count = 0;
+                node_ptr it = first_node.node_;
+                node_ptr first = it;
+                do {
+                    ++count;
+                    it = prev_in_group(it);
+                } while (it != first); // throws, strong
+                return count;
+            }
+#else
+            size_type group_count(local_iterator_base) const
+            {
+                return 1;
+            }
+#endif
+
+            // get_for_erase
+            //
+            // Find the pointer to a node, for use when erasing.
+            //
+            // no throw
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            node_ptr* get_for_erase(iterator_base r) const
+            {
+                node_ptr n = r.local_.node_;
+
+                // If the element isn't the first in its group, then
+                // the link to it will be found in the previous element
+                // in the group.
+                node_ptr* it = &prev_in_group(n)->links_.next_;
+                if(*it == n) return it;
+
+                // The element is the first in its group, so iterate
+                // throught the groups, checking against the first element.
+                it = &r.bucket_->first_;
+                while(*it != n) it = &HASH_TABLE_DATA::next_group(*it);
+                return it;
+            }
+#else
+            node_ptr* get_for_erase(iterator_base r) const
+            {
+                node_ptr n = r.local_.node_;
+                node_ptr* it = &r.bucket_->first_;
+                while(*it != n) it = &(*it)->links_.next_;
+                return it;
+            }
+#endif
+
+            // Link/Unlink/Move Node
+            //
+            // For adding nodes to buckets, removing them and moving them to a
+            // new bucket.
+            //
+            // no throw
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            void link_node(node_ptr n, local_iterator_base pos)
+            {
+                node_links& links = pos.node_->links_;
+
+                n->links_.next_ = links.group_prev_->links_.next_;
+                n->links_.group_prev_ = links.group_prev_;
+                links.group_prev_->links_.next_ = n;
+                links.group_prev_ = n;
+                ++size_;
+            }
+
+            void link_node(node_ptr n, bucket_ptr base)
+            {
+                n->links_.next_ = base->first_;
+                n->links_.group_prev_ = n;
+                base->first_ = n;
+                ++size_;
+                if(base < cached_begin_bucket_) {
+                    cached_begin_bucket_ = base;
+                    buckets_[bucket_count_].first_ = cached_begin_bucket_->first_;
+                    buckets_[bucket_count_+1].first_ = cached_begin_bucket_->first_;
+                }
+            }
+
+            void link_group(node_ptr n, bucket_ptr base, size_type count)
+            {
+                n->links_.group_prev_->links_.next_ = base->first_;
+                base->first_ = n;
+                size_ += count;
+                if(base < cached_begin_bucket_) {
+                    cached_begin_bucket_ = base;
+                    buckets_[bucket_count_].first_ = cached_begin_bucket_->first_;
+                    buckets_[bucket_count_+1].first_ = cached_begin_bucket_->first_;
+                }
+            }
+#else
+            void link_node(node_ptr n, bucket_ptr base)
+            {
+                n->links_.next_ = base->first_;
+                base->first_ = n;
+                ++size_;
+                if(base < cached_begin_bucket_) {
+                    cached_begin_bucket_ = base;
+                    buckets_[bucket_count_].first_ = cached_begin_bucket_->first_;
+                    buckets_[bucket_count_+1].first_ = cached_begin_bucket_->first_;
+                }
+            }
+
+            void link_group(node_ptr n, bucket_ptr base, size_type)
+            {
+                link_node(n, base);
+            }
+#endif
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            void unlink_node(iterator_base it)
+            {
+                node_ptr* pos = get_for_erase(it);
+                node_ptr n = *pos;
+                node_ptr next = n->links_.next_;
+
+                if(n->links_.group_prev_ == n) {
+                    // The deleted node is the sole node in the group, so
+                    // no need to unlink it from a goup.
+                }
+                else if(next && prev_in_group(next) == *pos)
+                {
+                    // The deleted node is not at the end of the group, so
+                    // change the link from the next node.
+                    prev_in_group(next) = n->links_.group_prev_;
+                }
+                else {
+                    // The deleted node is at the end of the group, so the
+                    // node in the group pointing to it is at the beginning
+                    // of the group. Find that to change its pointer.
+                    node_ptr it = n->links_.group_prev_;
+                    while(prev_in_group(it) != *pos) {
+                        it = prev_in_group(it);
+                    }
+                    prev_in_group(it) = n->links_.group_prev_;
+                }
+                *pos = next;
+                --size_;
+            }
+
+            size_type unlink_group(node_ptr* pos)
+            {
+                size_type count = group_count(local_iterator_base(*pos));
+                size_ -= count;
+                node_ptr last = last_in_group(*pos);
+                *pos = last->links_.next_;
+                return count;
+            }
+#else
+            void unlink_node(iterator_base n)
+            {
+                node_ptr* pos = get_for_erase(n);
+                *pos = (*pos)->links_.next_;
+                --size_;
+            }
+
+            size_type unlink_group(node_ptr* pos)
+            {
+                *pos = (*pos)->links_.next_;
+                --size_;
+                return 1;
+            }
+#endif
+
+            void unlink_nodes(iterator_base n)
+            {
+                node_ptr* it = get_for_erase(n);
+                split_group(*it);
+                unordered_detail::reset(*it);
+                size_ -= node_count(n.local_);
+            }
+
+            void unlink_nodes(iterator_base begin, iterator_base end)
+            {
+                BOOST_ASSERT(begin.bucket_ == end.bucket_);
+                local_iterator_base local_end = end.local_;
+
+                size_ -= node_count(begin.local_, local_end);
+                node_ptr* it = get_for_erase(begin);
+                split_group(*it, local_end.node_);
+                *it = local_end.node_;
+            }
+
+            void unlink_nodes(bucket_ptr base, iterator_base end)
+            {
+                BOOST_ASSERT(base == end.bucket_);
+
+                local_iterator_base local_end = end.local_;
+                split_group(local_end.node_);
+            
+                node_ptr ptr(base->first_);
+                base->first_ = local_end.node_;
+
+                size_ -= node_count(local_iterator_base(ptr), local_end);
+            }
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            // Break a ciruclar list into two, with split as the beginneing
+            // of the second group (if split is at the beginning then don't
+            // split).
+            node_ptr split_group(node_ptr split)
+            {
+                // If split is at the beginning of the group then there's
+                // nothing to split.
+                if(prev_in_group(split)->links_.next_ != split)
+                    return node_ptr();
+
+                // Find the start of the group.
+                node_ptr start = split;
+                do {
+                    start = prev_in_group(start);
+                } while(prev_in_group(start)->links_.next_ == start);
+
+                node_ptr last = prev_in_group(start);
+                prev_in_group(start) = prev_in_group(split);
+                prev_in_group(split) = last;
+
+                return start;
+            }
+
+            void split_group(node_ptr split1, node_ptr split2)
+            {
+                node_ptr begin1 = split_group(split1);
+                node_ptr begin2 = split_group(split2);
+
+                if(begin1 && split1 == begin2) {
+                    node_ptr end1 = prev_in_group(begin1);
+                    prev_in_group(begin1) = prev_in_group(begin2);
+                    prev_in_group(begin2) = end1;
+                }
+            }
+#else
+            void split_group(node_ptr)
+            {
+            }
+
+            void split_group(node_ptr, node_ptr)
+            {
+            }
+#endif
+
+            // throws, strong exception-safety:
+            node_ptr construct_node(value_type const& v)
+            {
+                node_constructor a(allocators_);
+                a.construct(v);
+                return a.release();
+            }
+
+            // Create Node
+            //
+            // Create a node and add it to the buckets in the given position.
+            //
+            // strong exception safety.
+
+            iterator_base create_node(value_type const& v, bucket_ptr base)
+            {
+                // throws, strong exception-safety:
+                node_ptr n = construct_node(v);
+
+                // Rest is no throw
+                link_node(n, base);
+                return iterator_base(base, n);
+            }
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            iterator_base create_node(value_type const& v, iterator_base position)
+            {
+                // throws, strong exception-safety:
+                node_ptr n = construct_node(v);
+
+                // Rest is no throw
+                link_node(n, position.local_);
+                return iterator_base(position.bucket_, n);
+            }
+
+            iterator_base create_node(value_type const& v,
+                    bucket_ptr base, local_iterator_base position)
+            {
+                // throws, strong exception-safety:
+                node_ptr n = construct_node(v);
+
+                // Rest is no throw
+                if(position.not_finished())
+                    link_node(n, position);
+                else
+                    link_node(n, base);
+
+                return iterator_base(base, n);
+            }
+#endif
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            void copy_group(local_iterator_base it, bucket_ptr dst)
+            {
+                local_iterator_base end = it;
+                end.next_group();
+                iterator_base pos = create_node(*it, dst);
+                for(it.increment(); it != end; it.increment())
+                    create_node(*it, pos);
+            }
+#else
+            void copy_group(local_iterator_base it, bucket_ptr dst)
+            {
+                create_node(*it, dst);
+            }
+#endif
+
+            // Delete Node
+            //
+            // Remove a node, or a range of nodes, from a bucket, and destroy
+            // them.
+            //
+            // no throw
+
+            void delete_to_bucket_end(node_ptr begin)
+            {
+                while(begin) {
+                    node_ptr node = begin;
+                    begin = begin->links_.next_;
+                    allocators_.destroy(node);
+                }
+            }
+
+            void delete_nodes(node_ptr begin, node_ptr end)
+            {
+                while(begin != end) {
+                    node_ptr node = begin;
+                    begin = begin->links_.next_;
+                    allocators_.destroy(node);
+                }
+            }
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+            void delete_group(node_ptr first_node)
+            {
+                delete_nodes(first_node, prev_in_group(first_node)->links_.next_);
+            }
+#else
+            void delete_group(node_ptr node)
+            {
+                allocators_.destroy(node);
+            }
+#endif
+
+            // Clear
+            //
+            // Remove all the nodes.
+            //
+            // no throw
+
+            void clear_bucket(bucket_ptr b)
+            {
+                node_ptr first_node = b->first_;
+                unordered_detail::reset(b->first_);
+                delete_to_bucket_end(first_node);
+            }
+
+            void clear()
+            {
+                bucket_ptr begin = buckets_;
+                bucket_ptr end = buckets_ + bucket_count_;
+
+                size_ = 0;
+                cached_begin_bucket_ = end;
+
+                while(begin != end) {
+                    clear_bucket(begin);
+                    ++begin;
+                }
+            }
+
+            // Erase
+            //
+            // Return type of erase(const_iterator):
+            // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1753.html#130
+            //
+            // no throw
+
+            iterator_base erase(iterator_base r)
+            {
+                BOOST_ASSERT(r != end());
+                iterator_base next = r;
+                next.increment();
+                unlink_node(r);
+                allocators_.destroy(r.local_.node_);
+                // r has been invalidated but its bucket is still valid
+                recompute_begin_bucket(r.bucket_, next.bucket_);
+                return next;
+            }
+
+            iterator_base erase(iterator_base r1, iterator_base r2)
+            {
+                if(r1 != r2)
+                {
+                    BOOST_ASSERT(r1 != end());
+
+                    if (r1.bucket_ == r2.bucket_) {
+                        unlink_nodes(r1, r2);
+                        delete_nodes(r1.local_.node_, r2.local_.node_);
+
+                        // No need to call recompute_begin_bucket because
+                        // the nodes are only deleted from one bucket, which
+                        // still contains r2 after the erase.
+                        BOOST_ASSERT(!r1.bucket_->empty());
+                    }
+                    else {
+                        BOOST_ASSERT(r1.bucket_ < r2.bucket_);
+
+                        unlink_nodes(r1);
+                        delete_to_bucket_end(r1.local_.node_);
+
+                        for(bucket_ptr i = r1.bucket_ + 1; i != r2.bucket_; ++i) {
+                            size_ -= node_count(local_iterator_base(i->first_));
+                            clear_bucket(i);
+                        }
+
+                        if(r2 != end()) {
+                            node_ptr first = r2.bucket_->first_;
+                            unlink_nodes(r2.bucket_, r2);
+                            delete_nodes(first, r2.local_.node_);
+                        }
+
+                        // r1 has been invalidated but its bucket is still
+                        // valid.
+                        recompute_begin_bucket(r1.bucket_, r2.bucket_);
+                    }
+                }
+
+                return r2;
+            }
+
+            // recompute_begin_bucket
+            //
+            // After an erase cached_begin_bucket_ might be left pointing to
+            // an empty bucket, so this is called to update it
+            //
+            // no throw
+
+            void recompute_begin_bucket(bucket_ptr b)
+            {
+                BOOST_ASSERT(!(b < cached_begin_bucket_));
+
+                if (size_ == 0) {
+                    cached_begin_bucket_ = buckets_ + bucket_count_;
+                }
+                else if(b == cached_begin_bucket_ && b->empty()) {
+                    do {
+                        ++cached_begin_bucket_;
+                    } while (cached_begin_bucket_->empty());
+                    
+                    buckets_[bucket_count_].first_ = cached_begin_bucket_->first_;
+                    buckets_[bucket_count_+1].first_ = cached_begin_bucket_->first_;
+                }
+            }
+
+            // This is called when a range has been erased
+            //
+            // no throw
+
+            void recompute_begin_bucket(bucket_ptr b1, bucket_ptr b2)
+            {
+                BOOST_ASSERT(!(b1 < cached_begin_bucket_) && !(b2 < b1));
+                BOOST_ASSERT(b2 == buckets_ + bucket_count_ || !b2->empty());
+
+                if(size_ == 0) {
+                    cached_begin_bucket_ = b2;
+                } else if(b1 == cached_begin_bucket_ && b1->empty()) {                    
+                    cached_begin_bucket_ = b2;
+
+                    buckets_[bucket_count_].first_ = cached_begin_bucket_->first_;
+                    buckets_[bucket_count_+1].first_ = cached_begin_bucket_->first_;
+                }
+            }
+
+            size_type erase_group(node_ptr* pos, bucket_ptr b)
+            {
+                node_ptr first_node = *pos;
+                size_type count = unlink_group(pos);
+                delete_group(first_node);
+
+                this->recompute_begin_bucket(b);
+
+                return count;
+            }
+        };
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+        template <>
+        class HASH_TABLE_DATA<int>
+        {
+        public:
+            typedef int size_type;
+            typedef int iterator_base;
+        };
+#endif
+
+        //
+        // Hash Table
+        //
+
+        template <class ValueType, class KeyType,
+            class Hash, class Pred,
+            class Alloc>
+        class HASH_TABLE
+            : public HASH_TABLE_DATA<Alloc>
+        {
+            typedef HASH_TABLE_DATA<Alloc> data;
+
+            typedef typename data::node_constructor node_constructor;
+            typedef typename data::bucket_ptr bucket_ptr;
+            typedef typename data::node_ptr node_ptr;
+
+        public:
+
+            typedef BOOST_DEDUCED_TYPENAME data::value_allocator value_allocator;
+            typedef BOOST_DEDUCED_TYPENAME data::node_allocator node_allocator;
+
+            // Type definitions
+
+            typedef KeyType key_type;
+            typedef Hash hasher;
+            typedef Pred key_equal;
+            typedef ValueType value_type;
+            typedef std::size_t size_type;
+
+            // iterators
+
+            typedef BOOST_DEDUCED_TYPENAME data::local_iterator_base local_iterator_base;
+            typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;
+
+        private:
+
+            class functions
+            {
+                std::pair<hasher, key_equal> functions_;
+
+            public:
+
+                functions(hasher const& h, key_equal const& k)
+                    : functions_(h, k) {}
+
+                hasher const& hash_function() const
+                {
+                    return functions_.first;
+                }
+
+                key_equal const& key_eq() const
+                {
+                    return functions_.second;
+                }
+            };
+
+            // Both hasher and key_equal's copy/assign can throw so double
+            // buffering is used to copy them. func_ points to the currently
+            // active function objects.
+
+            typedef functions HASH_TABLE::*functions_ptr;
+
+            functions func1_;
+            functions func2_;
+            functions_ptr func_;
+
+            float mlf_;
+            size_type max_load_;
+
+        public:
+
+            // Constructors
+            //
+            // In the constructors, if anything throws an exception,
+            // HASH_TABLE_DATA's destructor will clean up.
+
+            HASH_TABLE(size_type n,
+                    hasher const& hf, key_equal const& eq,
+                    value_allocator const& a)
+                : data(n, a),         // throws, cleans itself up
+                func1_(hf, eq),       // throws      "     "
+                func2_(hf, eq),       // throws      "     "
+                func_(&HASH_TABLE::func1_), // no throw
+                mlf_(1.0f)            // no throw
+            {
+                calculate_max_load(); // no throw
+            }
+
+            // Construct from iterators
+
+            // initial_size
+            //
+            // A helper function for the copy constructor to calculate how many
+            // nodes will be created if the iterator's support it. Might get it
+            // totally wrong for containers with unique keys.
+            //
+            // no throw
+
+            template <class I>
+            size_type initial_size(I i, I j, size_type n,
+                    boost::forward_traversal_tag)
+            {
+                // max load factor isn't set yet, but when it is, it'll be 1.0.
+                return (std::max)(static_cast<size_type>(std::distance(i, j)) + 1, n);
+            }
+
+            template <class I>
+            size_type initial_size(I, I, size_type n,
+                    boost::incrementable_traversal_tag)
+            {
+                return n;
+            }
+
+            template <class I>
+            size_type initial_size(I i, I j, size_type n)
+            {
+                BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
+                    iterator_traversal_tag;
+                return initial_size(i, j, n, iterator_traversal_tag);
+            }
+
+            template <class I>
+            HASH_TABLE(I i, I j, size_type n,
+                    hasher const& hf, key_equal const& eq,
+                    value_allocator const& a)
+                : data(initial_size(i, j, n), a),  // throws, cleans itself up
+                    func1_(hf, eq),                // throws    "      "
+                    func2_(hf, eq),                // throws    "      "
+                    func_(&HASH_TABLE::func1_),    // no throw
+                    mlf_(1.0f)                     // no throw
+            {
+                calculate_max_load(); // no throw
+
+                // This can throw, but HASH_TABLE_DATA's destructor will clean up.
+                insert(i, j);
+            }
+            // Copy Construct
+
+            HASH_TABLE(HASH_TABLE const& x)
+                : data(x, x.min_buckets_for_size(x.size())), // throws
+                func1_(x.current_functions()), // throws
+                func2_(x.current_functions()), // throws
+                func_(&HASH_TABLE::func1_), // no throw
+                mlf_(x.mlf_) // no throw
+            {
+                calculate_max_load(); // no throw
+
+                // This can throw, but HASH_TABLE_DATA's destructor will clean
+                // up.
+                copy_buckets(x, *this, current_functions());
+            }
+
+            // Assign
+            //
+            // basic exception safety, if copy_functions of reserver throws
+            // the container is left in a sane, empty state. If copy_buckets
+            // throws the container is left with whatever was successfully
+            // copied.
+
+            HASH_TABLE& operator=(HASH_TABLE const& x)
+            {
+                if(this != &x)
+                {
+                    this->clear();                        // no throw
+                    func_ = copy_functions(x);            // throws, strong
+                    mlf_ = x.mlf_;                        // no throw
+                    calculate_max_load();                 // no throw
+                    reserve(x.size());                    // throws
+                    copy_buckets(x, *this, current_functions()); // throws
+                }
+
+                return *this;
+            }
+
+            // Swap
+            //
+            // Swap's behaviour when allocators aren't equal is in dispute, see
+            // this paper for full details:
+            //
+            // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1599.html
+            //
+            // It lists 3 possible behaviours:
+            //
+            // 1 - If the allocators aren't equal then throw an exception.
+            // 2 - Reallocate the elements in the containers with the
+            //     appropriate allocators - messing up exception safety in
+            //     the process.
+            // 3 - Swap the allocators, hoping that the allocators have a
+            //     no-throw swap.
+            //
+            // The paper recommends #3.
+            //
+            // I've implemented all three, but actived #3 by default, to change
+            // it '#define BOOST_UNORDERED_SWAP_METHOD n' where n is the option.
+            //
+            // ----------------------------------------------------------------
+            //
+            // Strong exception safety (might change unused function objects)
+            //
+            // Can throw if hash or predicate object's copy constructor throws.
+            // If allocators are unequal:
+            //     Method 1: always throws.
+            //     Method 2: can throw if copying throws
+            //          (memory allocation/hash function object)
+            //     Method 3: Can throw if allocator's swap throws
+            //          (This one will go wrong if the allocator's swap throws
+            //           but since there's no guarantee what the allocators
+            //           will contain it's hard to know what to do. Maybe it
+            //           could double buffer the allocators).
+
+            void swap(HASH_TABLE& x)
+            {
+                // This only effects the function objects that aren't in use
+                // so it is strongly exception safe, via. double buffering.
+                functions_ptr new_func_this = copy_functions(x);       // throws
+                functions_ptr new_func_that = x.copy_functions(*this); // throws
+
+                if(this->allocators_ == x.allocators_) {
+                    this->data::swap(x); // no throw
+                }
+                else {
+#if BOOST_UNORDERED_SWAP_METHOD == 1
+                    throw std::runtime_error(
+                            "Swapping containers with different allocators.");
+#elif BOOST_UNORDERED_SWAP_METHOD == 2
+                    // Create new buckets in separate HASH_TABLE_DATA objects
+                    // which will clean up if anything throws an exception.
+                    // (all can throw, but with no effect as these are new objects).
+                    data new_this(*this, x.min_buckets_for_size(x.size_));
+                    copy_buckets(x, new_this, this->*new_func_this);
+
+                    data new_that(x, min_buckets_for_size(this->size_));
+                    x.copy_buckets(*this, new_that, x.*new_func_that);
+
+                    // Start updating the data here, no throw from now on.
+                    this->data::swap(new_this);
+                    x.data::swap(new_that);
+#elif BOOST_UNORDERED_SWAP_METHOD == 3
+                    // Note: I'm not sure that allocator swap is guaranteed to be no
+                    // throw.
+                    this->allocators_.swap(x.allocators_);
+                    this->data::swap(x);
+#else
+#error "Invalid swap method"
+#endif
+                }
+
+                // We've made it, the rest is no throw.
+                std::swap(mlf_, x.mlf_);
+
+                func_ = new_func_this;
+                x.func_ = new_func_that;
+
+                calculate_max_load();
+                x.calculate_max_load();
+            }
+
+        private:
+
+            functions const& current_functions() const
+            {
+                return this->*func_;
+            }
+
+            // This copies the given function objects into the currently unused
+            // function objects and returns a pointer, that func_ can later be
+            // set to, to commit the change.
+            //
+            // Strong exception safety (since only usued function objects are
+            // changed).
+            functions_ptr copy_functions(HASH_TABLE const& x)
+            {
+                // no throw:
+                functions_ptr ptr = func_ == &HASH_TABLE::func1_
+                    ? &HASH_TABLE::func2_ : &HASH_TABLE::func1_;
+                // throws, functions not in use, so strong
+                this->*ptr = x.current_functions();
+                return ptr;
+            }
+
+        public:
+
+            // accessors
+
+            // no throw
+            value_allocator get_allocator() const
+            {
+                return this->allocators_.value_alloc_;
+            }
+
+            // no throw
+            hasher const& hash_function() const
+            {
+                return current_functions().hash_function();
+            }
+
+            // no throw
+            key_equal const& key_eq() const
+            {
+                return current_functions().key_eq();
+            }
+
+            // no throw
+            size_type size() const
+            {
+                return this->size_;
+            }
+
+            // no throw
+            bool empty() const
+            {
+                return this->size_ == 0;
+            }
+
+            // no throw
+            size_type max_size() const
+            {
+                // size < mlf_ * count
+                return float_to_size_t(ceil(
+                        max_bucket_count() * mlf_)) - 1;
+            }
+
+            // strong safety
+            size_type bucket(key_type const& k) const
+            {
+                // hash_function can throw:
+                return this->index_from_hash(hash_function()(k));
+            }
+
+            // strong safety
+            bucket_ptr get_bucket(key_type const& k) const
+            {
+                return this->buckets_ + bucket(k);
+            }
+
+            // no throw
+            size_type bucket_count() const
+            {
+                return this->bucket_count_;
+            }
+
+            // no throw
+            size_type max_bucket_count() const
+            {
+                // -1 to account for the end marker.
+                return prev_prime(this->allocators_.bucket_alloc_.max_size() - 1);
+            }
+
+        private:
+
+            // no throw
+            size_type min_buckets_for_size(size_type n) const
+            {
+                BOOST_ASSERT(mlf_ != 0);
+
+                using namespace std;
+
+                // From 6.3.1/13:
+                // size < mlf_ * count
+                // => count > size / mlf_
+                //
+                // Or from rehash post-condition:
+                // count > size / mlf_
+                return static_cast<size_type>(floor(n / mlf_)) + 1;
+            }
+
+            // no throw
+            void calculate_max_load()
+            {
+                using namespace std;
+
+                // From 6.3.1/13:
+                // Only resize when size >= mlf_ * count
+                max_load_ = float_to_size_t(ceil(mlf_ * this->bucket_count_));
+            }
+
+            // basic exception safety
+            bool reserve(size_type n)
+            {
+                bool need_to_reserve = n >= max_load_;
+                // throws - basic:
+                if (need_to_reserve) rehash_impl(min_buckets_for_size(n));
+                BOOST_ASSERT(n < max_load_ || n > max_size());
+                return need_to_reserve;
+            }
+
+            // basic exception safety
+            //
+            // This version of reserve is called when inserting a range
+            // into a container with equivalent keys, it creates more buckets
+            // if the resulting load factor would be over 80% of the load
+            // factor. This is to try to avoid excessive rehashes.
+            bool reserve_extra(size_type n)
+            {
+                bool need_to_reserve = n >= max_load_;
+                // throws - basic:
+                if (need_to_reserve) {
+                    rehash_impl(static_cast<size_type>(floor(n / mlf_ * 1.25)) + 1);
+                }
+                BOOST_ASSERT(n < max_load_ || n > max_size());
+                return need_to_reserve;
+            }
+
+        public:
+
+            // no throw
+            float max_load_factor() const
+            {
+                return mlf_;
+            }
+
+            // no throw
+            void max_load_factor(float z)
+            {
+                BOOST_ASSERT(z > 0);
+                mlf_ = (std::max)(z, minimum_max_load_factor);
+                calculate_max_load();
+            }
+
+            // no throw
+            float load_factor() const
+            {
+                BOOST_ASSERT(this->bucket_count_ != 0);
+                return static_cast<float>(this->size_)
+                    / static_cast<float>(this->bucket_count_);
+            }
+
+        private:
+
+            // key extractors
+
+            // no throw
+            static key_type const& extract_key(value_type const& v)
+            {
+                return extract(v, (type_wrapper<value_type>*)0);
+            }
+
+            static key_type const& extract(value_type const& v,
+                    type_wrapper<key_type>*)
+            {
+                return v;
+            }
+
+            static key_type const& extract(value_type const& v,
+                    void*)
+            {
+                return v.first;
+            }
+
+        public:
+
+            // if hash function throws, basic exception safety
+            // strong otherwise.
+            void rehash(size_type n)
+            {
+                using namespace std;
+
+                // no throw:
+                size_type min_size = min_buckets_for_size(size());
+                // basic/strong:
+                rehash_impl(min_size > n ? min_size : n);
+
+                BOOST_ASSERT(bucket_count() > size() / max_load_factor()
+                        && bucket_count() >= n);
+            }
+
+        private:
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            void rehash_impl(size_type n)
+            {
+                n = next_prime(n); // no throw
+
+                if (n == bucket_count())  // no throw
+                    return;
+
+                data new_buckets(*this, n); // throws, seperate
+                move_buckets(*this, new_buckets, hash_function());
+                                                        // basic/no throw
+                new_buckets.swap(*this);                // no throw
+                calculate_max_load();                   // no throw
+            }
+
+            // move_buckets & copy_buckets
+            //
+            // if the hash function throws, basic excpetion safety
+            // no throw otherwise
+
+            static void move_buckets(data& src, data& dst, hasher const& hf)
+            {
+                BOOST_ASSERT(dst.size_ == 0);
+
+                // I'm assuming that this can't throw...
+                BOOST_ASSERT(src.allocators_ == dst.allocators_);
+
+                bucket_ptr end = src.buckets_ + src.bucket_count_;
+
+                for(; src.cached_begin_bucket_ != end;
+                        ++src.cached_begin_bucket_) {
+                    bucket_ptr src_bucket = src.cached_begin_bucket_;
+                    while(src_bucket->first_) {
+                        // Move the first group of equivalent nodes in
+                        // src_bucket to dst.
+
+                        // This next line throws iff the hash function throws.
+                        bucket_ptr dst_bucket = dst.buckets_ +
+                            dst.index_from_hash(
+                                hf(extract_key(src_bucket->first_->value_)));
+
+                        node_ptr n = src_bucket->first_;
+                        size_type count = src.unlink_group(&src_bucket->first_);
+                        dst.link_group(n, dst_bucket, count);
+                    }
+                }
+            }
+
+            // basic excpetion safety. If an exception is thrown this will
+            // leave dst partially filled.
+
+            static void copy_buckets(data const& src, data& dst, functions const& f)
+            {
+                BOOST_ASSERT(dst.size_ == 0);
+                // no throw:
+                bucket_ptr end = src.buckets_ + src.bucket_count_;
+                hasher const& hf = f.hash_function();
+
+                // no throw:
+                for(bucket_ptr i = src.cached_begin_bucket_; i != end; ++i) {
+                    // no throw:
+                    for(local_iterator_base it = src.begin(i);
+                            it.not_finished(); it.next_group()) {
+                        // hash function can throw.
+                        bucket_ptr dst_bucket = dst.buckets_ +
+                            dst.index_from_hash(hf(extract_key(*it)));
+                        // throws, strong
+                        dst.copy_group(it, dst_bucket);
+                    }
+                }
+            }
+
+        public:
+
+            // Insert functions
+            //
+            // basic exception safety, if hash function throws
+            // strong otherwise.
+
+#if BOOST_UNORDERED_HASH_EQUIVALENT
+
+            // Insert (equivalent key containers)
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            iterator_base insert(value_type const& v)
+            {
+                key_type const& k = extract_key(v);
+                size_type hash_value = hash_function()(k);
+                bucket_ptr bucket = this->buckets_
+                    + this->index_from_hash(hash_value);
+                local_iterator_base position = find_iterator(bucket, k);
+
+                // Create the node before rehashing in case it throws an
+                // exception (need strong safety in such a case).
+                node_constructor a(this->allocators_);
+                a.construct(v);
+
+                // reserve has basic exception safety if the hash function
+                // throws, strong otherwise.
+                if(reserve(size() + 1))
+                    bucket = this->buckets_ + this->index_from_hash(hash_value);
+
+                // Nothing after the point can throw.
+
+                node_ptr n = a.release();
+
+                // I'm relying on local_iterator_base not being invalidated by
+                // the rehash here.
+                if(position.not_finished())
+                    this->link_node(n, position);
+                else
+                    this->link_node(n, bucket);
+
+                return iterator_base(bucket, n);
+            }
+
+            // Insert (equivalent key containers)
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            iterator_base insert(iterator_base const& it, value_type const& v)
+            {
+                // equal can throw, but with no effects
+                if (it == this->end() || !equal(extract_key(v), *it)) {
+                    // Use the standard insert if the iterator doesn't point
+                    // to a matching key.
+                    return insert(v);
+                }
+                else {
+                    // Create the node before rehashing in case it throws an
+                    // exception (need strong safety in such a case).
+                    node_constructor a(this->allocators_);
+                    a.construct(v);
+
+                    // reserve has basic exception safety if the hash function
+                    // throws, strong otherwise.
+                    bucket_ptr base = reserve(size() + 1) ?
+                        get_bucket(extract_key(v)) : it.bucket_;
+
+                    // Nothing after this point can throw
+
+                    node_ptr n = a.release();
+                    this->link_node(n, it.local_);
+
+                    return iterator_base(base, n);
+                }
+            }
+
+            // Insert from iterator range (equivalent key containers)
+
+        private:
+
+            // if hash function throws, or inserting > 1 element, basic exception safety
+            // strong otherwise
+            template <class I>
+            void insert_for_range(I i, I j, forward_traversal_tag)
+            {
+                size_type distance = std::distance(i, j);
+                if(distance == 1) {
+                    insert(*i);
+                }
+                else {
+                    // Only require basic exception safety here
+                    reserve_extra(size() + distance);
+
+                    for (; i != j; ++i) {
+                        node_constructor a(this->allocators_);
+                        a.construct(*i);
+
+                        key_type const& k = extract_key(a.get()->value_);
+                        bucket_ptr bucket = get_bucket(k);
+                        local_iterator_base position = find_iterator(bucket, k);
+
+                        if(position.not_finished())
+                            this->link_node(a.release(), position);
+                        else
+                            this->link_node(a.release(), bucket);
+                    }
+                }
+            }
+
+            // if hash function throws, or inserting > 1 element, basic exception safety
+            // strong otherwise
+            template <class I>
+            void insert_for_range(I i, I j,
+                    boost::incrementable_traversal_tag)
+            {
+                // If only inserting 1 element, get the required
+                // safety since insert is only called once.
+                for (; i != j; ++i) insert(*i);
+            }
+
+        public:
+
+            // if hash function throws, or inserting > 1 element, basic exception safety
+            // strong otherwise
+            template <class I>
+            void insert(I i, I j)
+            {
+                BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
+                    iterator_traversal_tag;
+                insert_for_range(i, j, iterator_traversal_tag);
+            }
+#else
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            value_type& operator[](key_type const& k)
+            {
+                BOOST_STATIC_ASSERT((
+                            !boost::is_same<value_type, key_type>::value));
+                typedef BOOST_DEDUCED_TYPENAME value_type::second_type mapped_type;
+
+                size_type hash_value = hash_function()(k);
+                bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
+                local_iterator_base pos = find_iterator(bucket, k);
+
+                if (pos.not_finished())
+                    return *pos;
+                else
+                {
+                    // Side effects only in this block.
+
+                    // Create the node before rehashing in case it throws an
+                    // exception (need strong safety in such a case).
+                    node_constructor a(this->allocators_);
+                    a.construct(value_type(k, mapped_type()));
+
+                    // reserve has basic exception safety if the hash function
+                    // throws, strong otherwise.
+                    if (reserve(size() + 1))
+                        bucket = this->buckets_ + this->index_from_hash(hash_value);
+
+                    // Nothing after this point can throw.
+
+                    node_ptr n = a.release();
+                    this->link_node(n, bucket);
+
+                    return *local_iterator_base(n);
+                }
+            }
+
+            // Insert (unique keys)
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            std::pair<iterator_base, bool> insert(value_type const& v)
+            {
+                // No side effects in this initial code
+                key_type const& k = extract_key(v);
+                size_type hash_value = hash_function()(k);
+                bucket_ptr bucket = this->buckets_ + this->index_from_hash(hash_value);
+                local_iterator_base pos = find_iterator(bucket, k);
+                
+                if (pos.not_finished()) {
+                    // Found an existing key, return it (no throw).
+                    return std::pair<iterator_base, bool>(
+                        iterator_base(bucket, pos), false);
+
+                } else {
+                    // Doesn't already exist, add to bucket.
+                    // Side effects only in this block.
+
+                    // Create the node before rehashing in case it throws an
+                    // exception (need strong safety in such a case).
+                    node_constructor a(this->allocators_);
+                    a.construct(v);
+
+                    // reserve has basic exception safety if the hash function
+                    // throws, strong otherwise.
+                    if(reserve(size() + 1))
+                        bucket = this->buckets_ + this->index_from_hash(hash_value);
+
+                    // Nothing after this point can throw.
+
+                    node_ptr n = a.release();
+                    this->link_node(n, bucket);
+
+                    return std::pair<iterator_base, bool>(
+                        iterator_base(bucket, n), true);
+                }
+            }
+
+            // Insert (unique keys)
+
+            // if hash function throws, basic exception safety
+            // strong otherwise
+            iterator_base insert(iterator_base const& it, value_type const& v)
+            {
+                if(it != this->end() && equal(extract_key(v), *it))
+                    return it;
+                else
+                    return insert(v).first;
+            }
+
+            // Insert from iterators (unique keys)
+
+            template <class I>
+            size_type insert_size(I i, I j, boost::forward_traversal_tag)
+            {
+                return std::distance(i, j);
+            }
+
+            template <class I>
+            size_type insert_size(I i, I j, boost::incrementable_traversal_tag)
+            {
+                return 1;
+            }
+
+            template <class I>
+            size_type insert_size(I i, I j)
+            {
+                BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
+                    iterator_traversal_tag;
+                return insert_size(i, j, iterator_traversal_tag);
+            }
+
+            // if hash function throws, or inserting > 1 element, basic exception safety
+            // strong otherwise
+            template <class InputIterator>
+            void insert(InputIterator i, InputIterator j)
+            {
+                // If only inserting 1 element, get the required
+                // safety since insert is only called once.
+                for (; i != j; ++i) {
+                    // No side effects in this initial code
+                    size_type hash_value = hash_function()(extract_key(*i));
+                    bucket_ptr bucket = this->buckets_
+                        + this->index_from_hash(hash_value);
+                    local_iterator_base pos = find_iterator(bucket, extract_key(*i));
+                    
+                    if (!pos.not_finished()) {
+                        // Doesn't already exist, add to bucket.
+                        // Side effects only in this block.
+
+                        // Create the node before rehashing in case it throws an
+                        // exception (need strong safety in such a case).
+                        node_constructor a(this->allocators_);
+                        value_type const& v = *i;
+                        a.construct(v);
+
+                        // reserve has basic exception safety if the hash function
+                        // throws, strong otherwise.
+                        if(size() + 1 >= max_load_) {
+                            reserve(size() + insert_size(i, j));
+                            bucket = this->buckets_ + this->index_from_hash(hash_value);
+                        }
+
+                        // Nothing after this point can throw.
+                        this->link_node(a.release(), bucket);
+                    }
+                }
+            }
+#endif
+        public:
+
+            // erase
+
+            // no throw
+            iterator_base erase(iterator_base const& r)
+            {
+                return this->data::erase(r);
+            }
+
+            // strong exception safety
+            size_type erase(key_type const& k)
+            {
+                // No side effects in initial section
+                bucket_ptr bucket = get_bucket(k);
+                node_ptr* it = find_for_erase(bucket, k);
+
+                // No throw.
+                return *it ? this->erase_group(it, bucket) : 0;
+            }
+
+            // no throw
+            iterator_base erase(iterator_base const& r1, iterator_base const& r2)
+            {
+                return this->data::erase(r1, r2);
+            }
+
+            // count
+            //
+            // strong exception safety, no side effects
+            size_type count(key_type const& k) const
+            {
+                local_iterator_base it = find_iterator(k); // throws, strong
+                return it.not_finished() ? this->group_count(it) : 0;
+            }
+
+            // find
+            //
+            // strong exception safety, no side effects
+            iterator_base find(key_type const& k) const
+            {
+                bucket_ptr bucket = get_bucket(k);
+                local_iterator_base it = find_iterator(bucket, k);
+
+                if (it.not_finished())
+                    return iterator_base(bucket, it);
+                else
+                    return this->end();
+            }
+
+            // equal_range
+            //
+            // strong exception safety, no side effects
+            std::pair<iterator_base, iterator_base> equal_range(key_type const& k) const
+            {
+                bucket_ptr bucket = get_bucket(k);
+                local_iterator_base it = find_iterator(bucket, k);
+                if (it.not_finished()) {
+                    iterator_base first(iterator_base(bucket, it));
+                    iterator_base second(iterator_base(bucket, this->last_in_group(it.node_)));
+                    second.increment();
+                    return std::pair<iterator_base, iterator_base>(first, second);
+                }
+                else {
+                    return std::pair<iterator_base, iterator_base>(
+                            this->end(), this->end());
+                }
+            }
+
+        private:
+
+            // strong exception safety, no side effects
+            bool equal(key_type const& k, value_type const& v) const
+            {
+                return key_eq()(k, extract_key(v));
+            }
+
+            // strong exception safety, no side effects
+            local_iterator_base find_iterator(key_type const& k) const
+            {
+                return find_iterator(get_bucket(k), k);
+            }
+
+            // strong exception safety, no side effects
+            local_iterator_base find_iterator(bucket_ptr bucket,
+                    key_type const& k) const
+            {
+                local_iterator_base it = this->begin(bucket);
+                while (it.not_finished() && !equal(k, *it))
+                    it.next_group();
+
+                return it;
+            }
+
+            // strong exception safety, no side effects
+            node_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const
+            {
+                node_ptr* it = &bucket->first_;
+                while(*it && !equal(k, (*it)->value_))
+                    it = &this->next_group(*it);
+
+                return it;
+            }
+        };
+
+        // Iterators
+        
+        template <class Alloc> class HASH_ITERATOR;
+        template <class Alloc> class HASH_CONST_ITERATOR;
+        template <class Alloc> class HASH_LOCAL_ITERATOR;
+        template <class Alloc> class HASH_CONST_LOCAL_ITERATOR;
+        class iterator_access;
+
+        // Local Iterators
+        //
+        // all no throw
+
+        template <class Alloc>
+        class HASH_LOCAL_ITERATOR
+            : public boost::iterator <
+                std::forward_iterator_tag,
+                BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
+                std::ptrdiff_t,
+                BOOST_DEDUCED_TYPENAME allocator_pointer<Alloc>::type,
+                BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type >
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
+
+        private:
+            typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base;
+            typedef HASH_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
+
+            friend class HASH_CONST_LOCAL_ITERATOR<Alloc>;
+            base base_;
+
+        public:
+            HASH_LOCAL_ITERATOR() : base_() {}
+            explicit HASH_LOCAL_ITERATOR(base x) : base_(x) {}
+            BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
+                { return *base_; }
+            value_type* operator->() const { return &*base_; }
+            HASH_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
+            HASH_LOCAL_ITERATOR operator++(int) { HASH_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
+            bool operator==(HASH_LOCAL_ITERATOR x) const { return base_ == x.base_; }
+            bool operator==(const_local_iterator x) const { return base_ == x.base_; }
+            bool operator!=(HASH_LOCAL_ITERATOR x) const { return base_ != x.base_; }
+            bool operator!=(const_local_iterator x) const { return base_ != x.base_; }
+        };
+
+        template <class Alloc>
+        class HASH_CONST_LOCAL_ITERATOR
+            : public boost::iterator <
+                std::forward_iterator_tag,
+                BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
+                std::ptrdiff_t,
+                BOOST_DEDUCED_TYPENAME allocator_const_pointer<Alloc>::type,
+                BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type >
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
+
+        private:
+            typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base;
+            typedef HASH_LOCAL_ITERATOR<Alloc> local_iterator;
+            friend class HASH_LOCAL_ITERATOR<Alloc>;
+            base base_;
+
+        public:
+            HASH_CONST_LOCAL_ITERATOR() : base_() {}
+            explicit HASH_CONST_LOCAL_ITERATOR(base x) : base_(x) {}
+            HASH_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {}
+            BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
+                operator*() const { return *base_; }
+            value_type const* operator->() const { return &*base_; }
+            HASH_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
+            HASH_CONST_LOCAL_ITERATOR operator++(int) { HASH_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
+            bool operator==(local_iterator x) const { return base_ == x.base_; }
+            bool operator==(HASH_CONST_LOCAL_ITERATOR x) const { return base_ == x.base_; }
+            bool operator!=(local_iterator x) const { return base_ != x.base_; }
+            bool operator!=(HASH_CONST_LOCAL_ITERATOR x) const { return base_ != x.base_; }
+        };
+
+        // iterators
+        //
+        // all no throw
+
+
+        template <class Alloc>
+        class HASH_ITERATOR
+            : public boost::iterator <
+                std::forward_iterator_tag,
+                BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
+                std::ptrdiff_t,
+                BOOST_DEDUCED_TYPENAME allocator_pointer<Alloc>::type,
+                BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type >
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
+
+        private:
+            typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base;
+            typedef HASH_CONST_ITERATOR<Alloc> const_iterator;
+            friend class HASH_CONST_ITERATOR<Alloc>;
+            base base_;
+
+        public:
+
+            HASH_ITERATOR() : base_() {}
+            explicit HASH_ITERATOR(base const& x) : base_(x) {}
+            BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type
+                operator*() const { return *base_; }
+            value_type* operator->() const { return &*base_; }
+            HASH_ITERATOR& operator++() { base_.increment(); return *this; }
+            HASH_ITERATOR operator++(int) { HASH_ITERATOR tmp(base_); base_.increment(); return tmp; }
+            bool operator==(HASH_ITERATOR const& x) const { return base_ == x.base_; }
+            bool operator==(const_iterator const& x) const { return base_ == x.base_; }
+            bool operator!=(HASH_ITERATOR const& x) const { return base_ != x.base_; }
+            bool operator!=(const_iterator const& x) const { return base_ != x.base_; }
+        };
+
+        template <class Alloc>
+        class HASH_CONST_ITERATOR
+            : public boost::iterator <
+                std::forward_iterator_tag,
+                BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
+                std::ptrdiff_t,
+                BOOST_DEDUCED_TYPENAME allocator_const_pointer<Alloc>::type,
+                BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type >
+        {
+        public:
+            typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
+
+        private:
+            typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base;
+            typedef HASH_ITERATOR<Alloc> iterator;
+            friend class HASH_ITERATOR<Alloc>;
+            friend class iterator_access;
+            base base_;
+
+        public:
+
+            HASH_CONST_ITERATOR() : base_() {}
+            explicit HASH_CONST_ITERATOR(base const& x) : base_(x) {}
+            HASH_CONST_ITERATOR(iterator const& x) : base_(x.base_) {}
+            BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
+                operator*() const { return *base_; }
+            value_type const* operator->() const { return &*base_; }
+            HASH_CONST_ITERATOR& operator++() { base_.increment(); return *this; }
+            HASH_CONST_ITERATOR operator++(int) { HASH_CONST_ITERATOR tmp(base_); base_.increment(); return tmp; }
+            bool operator==(iterator const& x) const { return base_ == x.base_; }
+            bool operator==(HASH_CONST_ITERATOR const& x) const { return base_ == x.base_; }
+            bool operator!=(iterator const& x) const { return base_ != x.base_; }
+            bool operator!=(HASH_CONST_ITERATOR const& x) const { return base_ != x.base_; }
+        };
+    }
+}
+
+#undef HASH_TABLE
+#undef HASH_TABLE_DATA
+#undef HASH_ITERATOR
+#undef HASH_CONST_ITERATOR
+#undef HASH_LOCAL_ITERATOR
+#undef HASH_CONST_LOCAL_ITERATOR
+
+
+
Added: trunk/boost/spirit/home/support/detail/unordered_map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/unordered_map.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,660 @@
+
+// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
+// Copyright (C) 2005-2006 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UNORDERED_MAP_HPP_INCLUDED
+#define BOOST_UNORDERED_MAP_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#include <functional>
+#include <memory>
+
+#include <boost/spirit/home/support/detail/unordered/detail/hash_table.hpp>
+#include <boost/functional/hash.hpp>
+
+namespace boost
+{
+    template <class Key,
+        class T,
+        class Hash = hash<Key>,
+        class Pred = std::equal_to<Key>,
+        class Alloc = std::allocator<std::pair<const Key, T> > >
+    class unordered_map
+    {
+        typedef boost::unordered_detail::hash_types_unique_keys<
+            std::pair<const Key, T>, Key, Hash, Pred, Alloc
+        > implementation;
+
+        typename implementation::hash_table base;
+
+    public:
+
+        // types
+
+        typedef Key key_type;
+        typedef std::pair<const Key, T> value_type;
+        typedef T mapped_type;
+        typedef Hash hasher;
+        typedef Pred key_equal;
+
+        typedef Alloc allocator_type;
+        typedef typename allocator_type::pointer pointer;
+        typedef typename allocator_type::const_pointer const_pointer;
+        typedef typename allocator_type::reference reference;
+        typedef typename allocator_type::const_reference const_reference;
+
+        typedef typename implementation::size_type size_type;
+        typedef typename implementation::difference_type difference_type;
+
+        typedef typename implementation::iterator iterator;
+        typedef typename implementation::const_iterator const_iterator;
+        typedef typename implementation::local_iterator local_iterator;
+        typedef typename implementation::const_local_iterator const_local_iterator;
+
+        // construct/destroy/copy
+
+        explicit unordered_map(
+                size_type n = boost::unordered_detail::default_initial_bucket_count,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+            : base(n, hf, eql, a)
+        {
+        }
+
+        template <class InputIterator>
+        unordered_map(InputIterator f, InputIterator l)
+            : base(f, l, boost::unordered_detail::default_initial_bucket_count,
+                hasher(), key_equal(), allocator_type())
+        {
+        }
+
+        template <class InputIterator>
+        unordered_map(InputIterator f, InputIterator l,
+                size_type n,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+            : base(f, l, n, hf, eql, a)
+        {
+        }
+
+    private:
+
+        typename implementation::iterator_base const&
+            get(const_iterator const& it)
+        {
+            return boost::unordered_detail::iterator_access::get(it);
+        }
+
+    public:
+
+        allocator_type get_allocator() const
+        {
+            return base.get_allocator();
+        }
+
+        // size and capacity
+
+        bool empty() const
+        {
+            return base.empty();
+        }
+
+        size_type size() const
+        {
+            return base.size();
+        }
+
+        size_type max_size() const
+        {
+            return base.max_size();
+        }
+
+        // iterators
+
+        iterator begin()
+        {
+            return iterator(base.begin());
+        }
+
+        const_iterator begin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        iterator end()
+        {
+            return iterator(base.end());
+        }
+
+        const_iterator end() const
+        {
+            return const_iterator(base.end());
+        }
+
+        const_iterator cbegin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        const_iterator cend() const
+        {
+            return const_iterator(base.end());
+        }
+
+        // modifiers
+
+        std::pair<iterator, bool> insert(const value_type& obj)
+        {
+            return boost::unordered_detail::pair_cast<iterator, bool>(
+                    base.insert(obj));
+        }
+
+        iterator insert(iterator hint, const value_type& obj)
+        {
+            return iterator(base.insert(get(hint), obj));
+        }
+
+        const_iterator insert(const_iterator hint, const value_type& obj)
+        {
+            return const_iterator(base.insert(get(hint), obj));
+        }
+
+        template <class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+        {
+            base.insert(first, last);
+        }
+
+        iterator erase(iterator position)
+        {
+            return iterator(base.erase(get(position)));
+        }
+
+        const_iterator erase(const_iterator position)
+        {
+            return const_iterator(base.erase(get(position)));
+        }
+
+        size_type erase(const key_type& k)
+        {
+            return base.erase(k);
+        }
+
+        iterator erase(iterator first, iterator last)
+        {
+            return iterator(base.erase(get(first), get(last)));
+        }
+
+        const_iterator erase(const_iterator first, const_iterator last)
+        {
+            return const_iterator(base.erase(get(first), get(last)));
+        }
+
+        void clear()
+        {
+            base.clear();
+        }
+
+        void swap(unordered_map& other)
+        {
+            base.swap(other.base);
+        }
+
+        // observers
+
+        hasher hash_function() const
+        {
+            return base.hash_function();
+        }
+
+        key_equal key_eq() const
+        {
+            return base.key_eq();
+        }
+
+        mapped_type& operator[](const key_type &k)
+        {
+            return base[k].second;
+        }
+
+        // lookup
+
+        iterator find(const key_type& k)
+        {
+            return iterator(base.find(k));
+        }
+
+        const_iterator find(const key_type& k) const
+        {
+            return const_iterator(base.find(k));
+        }
+
+        size_type count(const key_type& k) const
+        {
+            return base.count(k);
+        }
+
+        std::pair<iterator, iterator>
+            equal_range(const key_type& k)
+        {
+            return boost::unordered_detail::pair_cast<iterator, iterator>(
+                    base.equal_range(k));
+        }
+
+        std::pair<const_iterator, const_iterator>
+            equal_range(const key_type& k) const
+        {
+            return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
+                    base.equal_range(k));
+        }
+
+        // bucket interface
+
+        size_type bucket_count() const
+        {
+            return base.bucket_count();
+        }
+
+        size_type max_bucket_count() const
+        {
+            return base.max_bucket_count();
+        }
+
+        size_type bucket_size(size_type n) const
+        {
+            return base.bucket_size(n);
+        }
+
+        size_type bucket(const key_type& k) const
+        {
+            return base.bucket(k);
+        }
+
+        local_iterator begin(size_type n)
+        {
+            return local_iterator(base.begin(n));
+        }
+
+        const_local_iterator begin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        local_iterator end(size_type n)
+        {
+            return local_iterator(base.end(n));
+        }
+
+        const_local_iterator end(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+
+#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
+        const_local_iterator cbegin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        const_local_iterator cend(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+#endif
+
+        // hash policy
+
+        float load_factor() const
+        {
+            return base.load_factor();
+        }
+
+        float max_load_factor() const
+        {
+            return base.max_load_factor();
+        }
+
+        void max_load_factor(float m)
+        {
+            base.max_load_factor(m);
+        }
+
+        void rehash(size_type n)
+        {
+            base.rehash(n);
+        }
+    }; // class template unordered_map
+
+    template <class K, class T, class H, class P, class A>
+    void swap(unordered_map<K, T, H, P, A> &m1,
+            unordered_map<K, T, H, P, A> &m2)
+    {
+        m1.swap(m2);
+    }
+
+    template <class Key,
+        class T,
+        class Hash = hash<Key>,
+        class Pred = std::equal_to<Key>,
+        class Alloc = std::allocator<std::pair<const Key, T> > >
+    class unordered_multimap
+    {
+        typedef boost::unordered_detail::hash_types_equivalent_keys<
+            std::pair<const Key, T>, Key, Hash, Pred, Alloc
+        > implementation;
+
+        typename implementation::hash_table base;
+
+        public:
+
+        // types
+
+        typedef Key key_type;
+        typedef std::pair<const Key, T> value_type;
+        typedef T mapped_type;
+        typedef Hash hasher;
+        typedef Pred key_equal;
+
+        typedef Alloc allocator_type;
+        typedef typename allocator_type::pointer pointer;
+        typedef typename allocator_type::const_pointer const_pointer;
+        typedef typename allocator_type::reference reference;
+        typedef typename allocator_type::const_reference const_reference;
+
+        typedef typename implementation::size_type size_type;
+        typedef typename implementation::difference_type difference_type;
+
+        typedef typename implementation::iterator iterator;
+        typedef typename implementation::const_iterator const_iterator;
+        typedef typename implementation::local_iterator local_iterator;
+        typedef typename implementation::const_local_iterator const_local_iterator;
+
+        // construct/destroy/copy
+
+        explicit unordered_multimap(
+                size_type n = boost::unordered_detail::default_initial_bucket_count,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+          : base(n, hf, eql, a)
+        {
+        }
+
+        template <class InputIterator>
+        unordered_multimap(InputIterator f, InputIterator l)
+            : base(f, l, boost::unordered_detail::default_initial_bucket_count,
+                hasher(), key_equal(), allocator_type())
+        {
+        }
+
+        template <class InputIterator>
+        unordered_multimap(InputIterator f, InputIterator l,
+                size_type n,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+          : base(f, l, n, hf, eql, a)
+        {
+        }
+
+    private:
+
+        typename implementation::iterator_base const&
+            get(const_iterator const& it)
+        {
+            return boost::unordered_detail::iterator_access::get(it);
+        }
+
+    public:
+
+        allocator_type get_allocator() const
+        {
+            return base.get_allocator();
+        }
+
+        // size and capacity
+
+        bool empty() const
+        {
+            return base.empty();
+        }
+
+        size_type size() const
+        {
+            return base.size();
+        }
+
+        size_type max_size() const
+        {
+            return base.max_size();
+        }
+
+        // iterators
+
+        iterator begin()
+        {
+            return iterator(base.begin());
+        }
+
+        const_iterator begin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        iterator end()
+        {
+            return iterator(base.end());
+        }
+
+        const_iterator end() const
+        {
+            return const_iterator(base.end());
+        }
+
+        const_iterator cbegin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        const_iterator cend() const
+        {
+            return const_iterator(base.end());
+        }
+
+        // modifiers
+
+        iterator insert(const value_type& obj)
+        {
+            return iterator(base.insert(obj));
+        }
+
+        iterator insert(iterator hint, const value_type& obj)
+        {
+            return iterator(base.insert(get(hint), obj));
+        }
+
+        const_iterator insert(const_iterator hint, const value_type& obj)
+        {
+            return const_iterator(base.insert(get(hint), obj));
+        }
+
+        template <class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+        {
+            base.insert(first, last);
+        }
+
+        iterator erase(iterator position)
+        {
+            return iterator(base.erase(get(position)));
+        }
+
+        const_iterator erase(const_iterator position)
+        {
+            return const_iterator(base.erase(get(position)));
+        }
+
+        size_type erase(const key_type& k)
+        {
+            return base.erase(k);
+        }
+
+        iterator erase(iterator first, iterator last)
+        {
+            return iterator(base.erase(get(first), get(last)));
+        }
+
+        const_iterator erase(const_iterator first, const_iterator last)
+        {
+            return const_iterator(base.erase(get(first), get(last)));
+        }
+
+        void clear()
+        {
+            base.clear();
+        }
+
+        void swap(unordered_multimap& other)
+        {
+            base.swap(other.base);
+        }
+
+        // observers
+
+        hasher hash_function() const
+        {
+            return base.hash_function();
+        }
+
+        key_equal key_eq() const
+        {
+            return base.key_eq();
+        }
+
+        // lookup
+
+        iterator find(const key_type& k)
+        {
+            return iterator(base.find(k));
+        }
+
+        const_iterator find(const key_type& k) const
+        {
+            return const_iterator(base.find(k));
+        }
+
+        size_type count(const key_type& k) const
+        {
+            return base.count(k);
+        }
+
+        std::pair<iterator, iterator>
+            equal_range(const key_type& k)
+        {
+            return boost::unordered_detail::pair_cast<iterator, iterator>(
+                    base.equal_range(k));
+        }
+
+        std::pair<const_iterator, const_iterator>
+            equal_range(const key_type& k) const
+        {
+            return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
+                    base.equal_range(k));
+        }
+
+        // bucket interface
+
+        size_type bucket_count() const
+        {
+            return base.bucket_count();
+        }
+
+        size_type max_bucket_count() const
+        {
+            return base.max_bucket_count();
+        }
+
+        size_type bucket_size(size_type n) const
+        {
+            return base.bucket_size(n);
+        }
+
+        size_type bucket(const key_type& k) const
+        {
+            return base.bucket(k);
+        }
+
+        local_iterator begin(size_type n)
+        {
+            return local_iterator(base.begin(n));
+        }
+
+        const_local_iterator begin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        local_iterator end(size_type n)
+        {
+            return local_iterator(base.end(n));
+        }
+
+        const_local_iterator end(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+
+#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
+        const_local_iterator cbegin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        const_local_iterator cend(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+#endif
+
+        // hash policy
+
+        float load_factor() const
+        {
+            return base.load_factor();
+        }
+
+        float max_load_factor() const
+        {
+            return base.max_load_factor();
+        }
+
+        void max_load_factor(float m)
+        {
+            base.max_load_factor(m);
+        }
+
+        void rehash(size_type n)
+        {
+            base.rehash(n);
+        }
+    }; // class template unordered_multimap
+
+    template <class K, class T, class H, class P, class A>
+    void swap(unordered_multimap<K, T, H, P, A> &m1,
+            unordered_multimap<K, T, H, P, A> &m2)
+    {
+        m1.swap(m2);
+    }
+
+} // namespace boost
+
+#endif // BOOST_UNORDERED_MAP_HPP_INCLUDED
Added: trunk/boost/spirit/home/support/detail/unordered_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/unordered_set.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,595 @@
+
+// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
+// Copyright (C) 2005-2006 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UNORDERED_SET_HPP_INCLUDED
+#define BOOST_UNORDERED_SET_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#include <functional>
+#include <memory>
+
+#include <spirit/support/detail/unordered/detail/hash_table.hpp>
+#include <boost/functional/hash.hpp>
+
+namespace boost
+{
+    template <class Value,
+        class Hash = hash<Value>,
+        class Pred = std::equal_to<Value>,
+        class Alloc = std::allocator<Value> >
+    class unordered_set
+    {
+        typedef boost::unordered_detail::hash_types_unique_keys<
+            Value, Value, Hash, Pred, Alloc
+        > implementation;
+
+        typename implementation::hash_table base;
+
+    public:
+
+        // types
+
+        typedef Value key_type;
+        typedef Value value_type;
+        typedef Hash hasher;
+        typedef Pred key_equal;
+
+        typedef Alloc allocator_type;
+        typedef typename allocator_type::pointer pointer;
+        typedef typename allocator_type::const_pointer const_pointer;
+        typedef typename allocator_type::reference reference;
+        typedef typename allocator_type::const_reference const_reference;
+
+        typedef typename implementation::size_type size_type;
+        typedef typename implementation::difference_type difference_type;
+
+        typedef typename implementation::const_iterator iterator;
+        typedef typename implementation::const_iterator const_iterator;
+        typedef typename implementation::const_local_iterator local_iterator;
+        typedef typename implementation::const_local_iterator const_local_iterator;
+
+        // construct/destroy/copy
+
+        explicit unordered_set(
+                size_type n = boost::unordered_detail::default_initial_bucket_count,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+            : base(n, hf, eql, a)
+        {
+        }
+
+        template <class InputIterator>
+        unordered_set(InputIterator f, InputIterator l)
+            : base(f, l, boost::unordered_detail::default_initial_bucket_count,
+                hasher(), key_equal(), allocator_type())
+        {
+        }
+
+        template <class InputIterator>
+        unordered_set(InputIterator f, InputIterator l, size_type n,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+            : base(f, l, n, hf, eql, a)
+        {
+        }
+
+    private:
+
+        typename implementation::iterator_base const&
+            get(const_iterator const& it)
+        {
+            return boost::unordered_detail::iterator_access::get(it);
+        }
+
+    public:
+
+        allocator_type get_allocator() const
+        {
+            return base.get_allocator();
+        }
+
+        // size and capacity
+
+        bool empty() const
+        {
+            return base.empty();
+        }
+
+        size_type size() const
+        {
+            return base.size();
+        }
+
+        size_type max_size() const
+        {
+            return base.max_size();
+        }
+
+        // iterators
+
+        iterator begin()
+        {
+            return iterator(base.begin());
+        }
+
+        const_iterator begin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        iterator end()
+        {
+            return iterator(base.end());
+        }
+
+        const_iterator end() const
+        {
+            return const_iterator(base.end());
+        }
+
+        const_iterator cbegin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        const_iterator cend() const
+        {
+            return const_iterator(base.end());
+        }
+
+        // modifiers
+
+        std::pair<iterator, bool> insert(const value_type& obj)
+        {
+            return boost::unordered_detail::pair_cast<iterator, bool>(
+                    base.insert(obj));
+        }
+
+        const_iterator insert(const_iterator hint, const value_type& obj)
+        {
+            return const_iterator(base.insert(get(hint), obj));
+        }
+
+        template <class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+        {
+            base.insert(first, last);
+        }
+
+        const_iterator erase(const_iterator position)
+        {
+            return const_iterator(base.erase(get(position)));
+        }
+
+        size_type erase(const key_type& k)
+        {
+            return base.erase(k);
+        }
+
+        const_iterator erase(const_iterator first, const_iterator last)
+        {
+            return const_iterator(base.erase(get(first), get(last)));
+        }
+
+        void clear()
+        {
+            base.clear();
+        }
+
+        void swap(unordered_set& other)
+        {
+            base.swap(other.base);
+        }
+
+        // observers
+
+        hasher hash_function() const
+        {
+            return base.hash_function();
+        }
+
+        key_equal key_eq() const
+        {
+            return base.key_eq();
+        }
+
+        // lookup
+
+        const_iterator find(const key_type& k) const
+        {
+            return const_iterator(base.find(k));
+        }
+
+        size_type count(const key_type& k) const
+        {
+            return base.count(k);
+        }
+
+        std::pair<const_iterator, const_iterator>
+            equal_range(const key_type& k) const
+        {
+            return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
+                    base.equal_range(k));
+        }
+
+        // bucket interface
+
+        size_type bucket_count() const
+        {
+            return base.bucket_count();
+        }
+
+        size_type max_bucket_count() const
+        {
+            return base.max_bucket_count();
+        }
+
+        size_type bucket_size(size_type n) const
+        {
+            return base.bucket_size(n);
+        }
+
+        size_type bucket(const key_type& k) const
+        {
+            return base.bucket(k);
+        }
+
+        local_iterator begin(size_type n)
+        {
+            return local_iterator(base.begin(n));
+        }
+
+        const_local_iterator begin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        local_iterator end(size_type n)
+        {
+            return local_iterator(base.end(n));
+        }
+
+        const_local_iterator end(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+
+#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
+        const_local_iterator cbegin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        const_local_iterator cend(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+#endif
+
+        // hash policy
+
+        float load_factor() const
+        {
+            return base.load_factor();
+        }
+
+        float max_load_factor() const
+        {
+            return base.max_load_factor();
+        }
+
+        void max_load_factor(float m)
+        {
+            base.max_load_factor(m);
+        }
+
+        void rehash(size_type n)
+        {
+            base.rehash(n);
+        }
+    }; // class template unordered_set
+
+    template <class T, class H, class P, class A>
+    void swap(unordered_set<T, H, P, A> &m1,
+            unordered_set<T, H, P, A> &m2)
+    {
+        m1.swap(m2);
+    }
+
+    template <class Value,
+        class Hash = hash<Value>,
+        class Pred = std::equal_to<Value>,
+        class Alloc = std::allocator<Value> >
+    class unordered_multiset
+    {
+        typedef boost::unordered_detail::hash_types_equivalent_keys<
+            Value, Value, Hash, Pred, Alloc
+        > implementation;
+
+        typename implementation::hash_table base;
+
+    public:
+
+        //types
+
+        typedef Value key_type;
+        typedef Value value_type;
+        typedef Hash hasher;
+        typedef Pred key_equal;
+
+        typedef Alloc allocator_type;
+        typedef typename allocator_type::pointer pointer;
+        typedef typename allocator_type::const_pointer const_pointer;
+        typedef typename allocator_type::reference reference;
+        typedef typename allocator_type::const_reference const_reference;
+
+        typedef typename implementation::size_type size_type;
+        typedef typename implementation::difference_type difference_type;
+
+        typedef typename implementation::const_iterator iterator;
+        typedef typename implementation::const_iterator const_iterator;
+        typedef typename implementation::const_local_iterator local_iterator;
+        typedef typename implementation::const_local_iterator const_local_iterator;
+
+        // construct/destroy/copy
+
+        explicit unordered_multiset(
+                size_type n = boost::unordered_detail::default_initial_bucket_count,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+          : base(n, hf, eql, a)
+        {
+        }
+
+        template <class InputIterator>
+        unordered_multiset(InputIterator f, InputIterator l)
+            : base(f, l, boost::unordered_detail::default_initial_bucket_count,
+                hasher(), key_equal(), allocator_type())
+        {
+        }
+
+        template <class InputIterator>
+        unordered_multiset(InputIterator f, InputIterator l, size_type n,
+                const hasher &hf = hasher(),
+                const key_equal &eql = key_equal(),
+                const allocator_type &a = allocator_type())
+          : base(f, l, n, hf, eql, a)
+        {
+        }
+
+    private:
+
+        typename implementation::iterator_base const&
+            get(const_iterator const& it)
+        {
+            return boost::unordered_detail::iterator_access::get(it);
+        }
+
+    public:
+
+        allocator_type get_allocator() const
+        {
+            return base.get_allocator();
+        }
+
+        // size and capacity
+
+        bool empty() const
+        {
+            return base.empty();
+        }
+
+        size_type size() const
+        {
+            return base.size();
+        }
+
+        size_type max_size() const
+        {
+            return base.max_size();
+        }
+
+        // iterators
+
+        iterator begin()
+        {
+            return iterator(base.begin());
+        }
+
+        const_iterator begin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        iterator end()
+        {
+            return iterator(base.end());
+        }
+
+        const_iterator end() const
+        {
+            return const_iterator(base.end());
+        }
+
+        const_iterator cbegin() const
+        {
+            return const_iterator(base.begin());
+        }
+
+        const_iterator cend() const
+        {
+            return const_iterator(base.end());
+        }
+
+        // modifiers
+
+        iterator insert(const value_type& obj)
+        {
+            return iterator(base.insert(obj));
+        }
+
+        const_iterator insert(const_iterator hint, const value_type& obj)
+        {
+            return const_iterator(base.insert(get(hint), obj));
+        }
+
+        template <class InputIterator>
+            void insert(InputIterator first, InputIterator last)
+        {
+            base.insert(first, last);
+        }
+
+        const_iterator erase(const_iterator position)
+        {
+            return const_iterator(base.erase(get(position)));
+        }
+
+        size_type erase(const key_type& k)
+        {
+            return base.erase(k);
+        }
+
+        const_iterator erase(const_iterator first, const_iterator last)
+        {
+            return const_iterator(base.erase(get(first), get(last)));
+        }
+
+        void clear()
+        {
+            base.clear();
+        }
+
+        void swap(unordered_multiset& other)
+        {
+            base.swap(other.base);
+        }
+
+        // observers
+
+        hasher hash_function() const
+        {
+            return base.hash_function();
+        }
+
+        key_equal key_eq() const
+        {
+            return base.key_eq();
+        }
+
+        // lookup
+
+        const_iterator find(const key_type& k) const
+        {
+            return const_iterator(base.find(k));
+        }
+
+        size_type count(const key_type& k) const
+        {
+            return base.count(k);
+        }
+
+        std::pair<const_iterator, const_iterator>
+            equal_range(const key_type& k) const
+        {
+            return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
+                    base.equal_range(k));
+        }
+
+        // bucket interface
+
+        size_type bucket_count() const
+        {
+            return base.bucket_count();
+        }
+
+        size_type max_bucket_count() const
+        {
+            return base.max_bucket_count();
+        }
+
+        size_type bucket_size(size_type n) const
+        {
+            return base.bucket_size(n);
+        }
+
+        size_type bucket(const key_type& k) const
+        {
+            return base.bucket(k);
+        }
+
+        local_iterator begin(size_type n)
+        {
+            return local_iterator(base.begin(n));
+        }
+
+        const_local_iterator begin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        local_iterator end(size_type n)
+        {
+            return local_iterator(base.end(n));
+        }
+
+        const_local_iterator end(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+
+#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
+        const_local_iterator cbegin(size_type n) const
+        {
+            return const_local_iterator(base.begin(n));
+        }
+
+        const_local_iterator cend(size_type n) const
+        {
+            return const_local_iterator(base.end(n));
+        }
+#endif
+
+        // hash policy
+
+        float load_factor() const
+        {
+            return base.load_factor();
+        }
+
+        float max_load_factor() const
+        {
+            return base.max_load_factor();
+        }
+
+        void max_load_factor(float m)
+        {
+            base.max_load_factor(m);
+        }
+
+        void rehash(size_type n)
+        {
+            base.rehash(n);
+        }
+    }; // class template unordered_multiset
+
+    template <class T, class H, class P, class A>
+    void swap(unordered_multiset<T, H, P, A> &m1,
+            unordered_multiset<T, H, P, A> &m2)
+    {
+        m1.swap(m2);
+    }
+
+} // namespace boost
+
+#endif // BOOST_UNORDERED_SET_HPP_INCLUDED
Added: trunk/boost/spirit/home/support/detail/values.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/values.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,120 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_VALUES_JAN_07_2007_0802PM)
+#define BOOST_SPIRIT_VALUES_JAN_07_2007_0802PM
+
+#include <boost/fusion/include/is_sequence.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace detail
+{
+    template <typename T>
+    struct not_is_variant
+      : mpl::true_ {};
+
+    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+    struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+      : mpl::false_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  All parsers and generators have specific attribute or parameter types.
+    //  Spirit parsers are passed an attribute and Spirit generators
+    //  are passed a parameter; these are either references to the expected
+    //  type, or an unused_type -- to flag that we do not care about the
+    //  attribute/parameter. 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.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ValueType>
+    struct make_value
+    {
+        static ValueType call(unused_type)
+        {
+            return ValueType(); // synthesize the attribute/parameter
+        }
+
+        template <typename T>
+        static T& call(T& value)
+        {
+            return value; // just pass the one provided
+        }
+
+        template <typename T>
+        static T const& call(T const& value)
+        {
+            return value; // just pass the one provided
+        }
+    };
+
+    template <typename ValueType>
+    struct make_value<ValueType&> : make_value<ValueType>
+    {
+    };
+
+    template <>
+    struct make_value<unused_type>
+    {
+        static unused_type call(unused_type)
+        {
+            return unused;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  pass_value determines how we pass attributes and parameters to semantic
+    //  actions. Basically, all SAs receive the arguments in a tuple. So, if
+    //  the argument to be passed is not a tuple, wrap it in one.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename ValueType>
+    struct pass_value
+    {
+        typedef
+            mpl::and_<
+                fusion::traits::is_sequence<ValueType>
+              , detail::not_is_variant<ValueType>
+            >
+        is_sequence;
+
+        typedef typename
+            mpl::if_<
+                is_sequence
+              , ValueType&
+              , fusion::vector<ValueType&> const
+            >::type
+        type;
+
+        static ValueType&
+        call(ValueType& arg, mpl::true_)
+        {
+            // arg is a fusion sequence (except a variant) return it as-is.
+            return arg;
+        }
+
+        static fusion::vector<ValueType&> const
+        call(ValueType& seq, mpl::false_)
+        {
+            // arg is a not fusion sequence wrap it in a fusion::vector.
+            return fusion::vector<ValueType&>(seq);
+        }
+
+        static type
+        call(ValueType& arg)
+        {
+            return call(arg, is_sequence());
+        }
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/detail/what_function.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/detail/what_function.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,37 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_WHAT_FUNCTION_APR_22_2007_0236PM)
+#define SPIRIT_WHAT_FUNCTION_APR_22_2007_0236PM
+
+#include <string>
+
+namespace boost { namespace spirit { namespace detail
+{
+    struct what_function
+    {
+        what_function(std::string& str)
+          : str(str), first(true)
+        {
+        }
+
+        template <typename Component>
+        void operator()(Component const& component) const
+        {
+            if (first)
+                first = false;
+            else
+                str += ", ";
+            typedef typename Component::director director;
+            str += director::what(component);
+        }
+
+        std::string& str;
+        mutable bool first;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iso8859_1.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iso8859_1.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_ISO8859_1_JAN_31_2006_0529PM)
+#define SPIRIT_ISO8859_1_JAN_31_2006_0529PM
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit { namespace iso8859_1
+{
+    typedef spirit::char_class::iso8859_1 char_set;
+    namespace tag = spirit::char_class::tag;
+    
+    template <typename Class>
+    struct make_tag 
+      : proto::terminal<spirit::char_class::key<char_set, Class> > {};
+
+    typedef make_tag<tag::alnum>::type alnum_type;
+    typedef make_tag<tag::alpha>::type alpha_type;
+    typedef make_tag<tag::blank>::type blank_type;
+    typedef make_tag<tag::cntrl>::type cntrl_type;
+    typedef make_tag<tag::digit>::type digit_type;
+    typedef make_tag<tag::graph>::type graph_type;
+    typedef make_tag<tag::print>::type print_type;
+    typedef make_tag<tag::punct>::type punct_type;
+    typedef make_tag<tag::space>::type space_type;
+    typedef make_tag<tag::xdigit>::type xdigit_type;
+
+    alnum_type const alnum = {{}};
+    alpha_type const alpha = {{}};
+    blank_type const blank = {{}};
+    cntrl_type const cntrl = {{}};
+    digit_type const digit = {{}};
+    graph_type const graph = {{}};
+    print_type const print = {{}};
+    punct_type const punct = {{}};
+    space_type const space = {{}};
+    xdigit_type const xdigit = {{}};
+    
+    typedef proto::terminal<
+        spirit::char_class::no_case_tag<char_set> >::type 
+    no_case_type;
+
+    no_case_type const no_case = no_case_type();
+
+    typedef proto::terminal<
+        spirit::char_class::lower_case_tag<char_set> >::type 
+    lower_type;
+    typedef proto::terminal<
+        spirit::char_class::upper_case_tag<char_set> >::type 
+    upper_type;
+
+    lower_type const lower = lower_type();
+    upper_type const upper = upper_type();
+
+#if defined(__GNUC__)
+    inline void silence_unused_warnings__iso8859_1()
+    {
+        (void) alnum; (void) alpha; (void) blank; (void) cntrl; (void) digit; 
+        (void) graph; (void) print; (void) punct; (void) space;  (void) xdigit;
+    }
+#endif
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,96 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM)
+#define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <exception>    // for std::exception
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class illegal_backtracking
+    //  thrown by buf_id_check CheckingPolicy if an instance of an iterator is
+    //  used after another one has invalidated the queue
+    ///////////////////////////////////////////////////////////////////////////
+    class illegal_backtracking : public std::exception
+    {
+    public:
+        illegal_backtracking() throw() {}
+        ~illegal_backtracking() throw() {}
+
+        char const* what() const throw()
+        { 
+            return "boost::spirit::multi_pass::illegal_backtracking"; 
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////////
+    //  class buf_id_check
+    //  Implementation of the CheckingPolicy used by multi_pass
+    //  This policy is most effective when used together with the std_deque
+    //  StoragePolicy.
+    // 
+    //  If used with the fixed_size_queue StoragePolicy, it will not detect
+    //  iterator dereferences that are out of the range of the queue.
+    ///////////////////////////////////////////////////////////////////////////////
+    struct buf_id_check
+    {
+        ///////////////////////////////////////////////////////////////////////
+        struct unique //: detail::default_checking_policy
+        {
+            unique()
+              : buf_id(0)
+            {}
+
+            unique(unique const& x)
+              : buf_id(x.buf_id)
+            {}
+
+            void swap(unique& x)
+            {
+                spirit::detail::swap(buf_id, x.buf_id);
+            }
+
+            // called to verify that everything is ok.
+            template <typename MultiPass>
+            static void check(MultiPass const& mp) 
+            {
+                if (mp.buf_id != mp.shared->shared_buf_id)
+                    boost::throw_exception(illegal_backtracking());
+            }
+
+            // called from multi_pass::clear_queue, so we can increment the count
+            template <typename MultiPass>
+            static void clear_queue(MultiPass& mp)
+            {
+                ++mp.shared->shared_buf_id;
+                ++mp.buf_id;
+            }
+
+            template <typename MultiPass>
+            static void destroy(MultiPass& mp) 
+            {}
+
+        protected:
+            unsigned long buf_id;
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        struct shared
+        {
+            shared() : shared_buf_id(0) {}
+            unsigned long shared_buf_id;
+        };
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,481 @@
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
+#define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
+
+#include <boost/type_traits/is_empty.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The purpose of the multi_pass_unique template is to eliminate 
+    //  empty policy classes (policies not containing any data items) from the 
+    //  multiple inheritance chain. This is necessary since a compiler is not 
+    //  allowed to apply the empty base optimization if multiple inheritance is 
+    //  involved (or at least most compilers fail to apply it).
+    //  Additionally this can be used to combine separate policies into one 
+    //  single multi_pass_policy as required by the multi_pass template
+    ///////////////////////////////////////////////////////////////////////////
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+    // without partial template specialization there is nothing much to do in 
+    // terms of empty base optimization anyways...
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique 
+      : Ownership, Checking, Input, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) : Input(x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Ownership::destroy(mp);
+            Checking::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Ownership::swap(x);
+            this->Checking::swap(x);
+            this->Input::swap(x);
+            this->Storage::swap(x);
+        }
+    };
+#else
+    ///////////////////////////////////////////////////////////////////////////
+    // select the correct derived classes based on if a policy is empty
+    template <
+        typename T, 
+        typename Ownership, typename Checking, typename Input, typename Storage,
+        bool OwnershipIsEmpty = boost::is_empty<Ownership>::value, 
+        bool CheckingIsEmpty = boost::is_empty<Checking>::value, 
+        bool InputIsEmpty = boost::is_empty<Input>::value>
+    struct multi_pass_unique;
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            false, false, false>
+      : Ownership, Checking, Input, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) : Input(x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Ownership::destroy(mp);
+            Checking::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Ownership::swap(x);
+            this->Checking::swap(x);
+            this->Input::swap(x);
+            this->Storage::swap(x);
+        }
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            false, false, true>
+      : Ownership, Checking, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) {}
+        
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Ownership::destroy(mp);
+            Checking::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Ownership::swap(x);
+            this->Checking::swap(x);
+            this->Storage::swap(x);
+        }
+        
+        // implement input policy functions by forwarding to the Input type
+        template <typename MultiPass, typename TokenType>
+        inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
+            { return Input::advance_input(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
+            { return Input::input_at_eof(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
+            { return Input::input_is_valid(mp, curtok); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            false, true, false>
+      : Ownership, Input, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) : Input(x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Ownership::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Ownership::swap(x);
+            this->Input::swap(x);
+            this->Storage::swap(x);
+        }
+        
+        // checking policy functions are forwarded to the Checking type
+        template <typename MultiPass>
+        inline static void check(MultiPass const& mp) 
+            { Checking::check(mp); }
+
+        template <typename MultiPass>
+        inline static void clear_queue(MultiPass& mp) 
+            { Checking::clear_queue(mp); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            false, true, true>
+      : Ownership, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Ownership::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Ownership::swap(x);
+            this->Storage::swap(x);
+        }
+
+        // implement input policy functions by forwarding to the Input type
+        template <typename MultiPass, typename TokenType>
+        inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
+            { return Input::advance_input(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
+            { return Input::input_at_eof(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
+            { return Input::input_is_valid(mp, curtok); }
+
+        // checking policy functions are forwarded to the Checking type
+        template <typename MultiPass>
+        inline static void check(MultiPass const& mp) 
+            { Checking::check(mp); }
+
+        template <typename MultiPass>
+        inline static void clear_queue(MultiPass& mp) 
+            { Checking::clear_queue(mp); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            true, false, false>
+      : Checking, Input, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) : Input(x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Checking::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Checking::swap(x);
+            this->Input::swap(x);
+            this->Storage::swap(x);
+        }
+
+        // ownership policy functions are forwarded to the Ownership type
+        template <typename MultiPass>
+        inline static void clone(MultiPass& mp) 
+            { Ownership::clone(mp); }
+
+        template <typename MultiPass>
+        inline static bool release(MultiPass& mp)
+            { return Ownership::release(mp); }
+        
+        template <typename MultiPass>
+        inline static bool is_unique(MultiPass const& mp)
+            { return Ownership::is_unique(mp); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            true, false, true>
+      : Checking, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Checking::destroy(mp);
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Checking::swap(x);
+            this->Storage::swap(x);
+        }
+
+        // implement input policy functions by forwarding to the Input type
+        template <typename MultiPass, typename TokenType>
+        inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
+            { return Input::advance_input(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
+            { return Input::input_at_eof(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
+            { return Input::input_is_valid(mp, curtok); }
+
+        // ownership policy functions are forwarded to the Ownership type
+        template <typename MultiPass>
+        inline static void clone(MultiPass& mp) 
+            { Ownership::clone(mp); }
+
+        template <typename MultiPass>
+        inline static bool release(MultiPass& mp)
+            { return Ownership::release(mp); }
+        
+        template <typename MultiPass>
+        inline static bool is_unique(MultiPass const& mp)
+            { return Ownership::is_unique(mp); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            true, true, false>
+      : Input, Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& x) : Input(x) {}
+        
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Input::swap(x);
+            this->Storage::swap(x);
+        }
+        
+        // checking policy functions are forwarded to the Checking type
+        template <typename MultiPass>
+        inline static void check(MultiPass const& mp) 
+            { Checking::check(mp); }
+
+        template <typename MultiPass>
+        inline static void clear_queue(MultiPass& mp) 
+            { Checking::clear_queue(mp); }
+
+        // ownership policy functions are forwarded to the Ownership type
+        template <typename MultiPass>
+        inline static void clone(MultiPass& mp) 
+            { Ownership::clone(mp); }
+
+        template <typename MultiPass>
+        inline static bool release(MultiPass& mp)
+            { return Ownership::release(mp); }
+        
+        template <typename MultiPass>
+        inline static bool is_unique(MultiPass const& mp)
+            { return Ownership::is_unique(mp); }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Ownership, typename Checking, 
+        typename Input, typename Storage>
+    struct multi_pass_unique<T, Ownership, Checking, Input, Storage, 
+            true, true, true>
+      : Storage
+    {
+        multi_pass_unique() {}
+        multi_pass_unique(T const& /*x*/) {}
+
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp)
+        {
+            Input::destroy(mp);
+            Storage::destroy(mp);
+        }
+        void swap(multi_pass_unique& x) 
+        {
+            this->Storage::swap(x);
+        }
+
+        // implement input policy functions by forwarding to the Input type
+        template <typename MultiPass, typename TokenType>
+        inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
+            { return Input::advance_input(mp, curtok); }
+
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
+            { return Input::input_at_eof(mp, curtok); }
+        
+        template <typename MultiPass, typename TokenType>
+        inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
+            { return Input::input_is_valid(mp, curtok); }
+
+        // checking policy functions are forwarded to the Checking type
+        template <typename MultiPass>
+        inline static void check(MultiPass const& mp) 
+            { Checking::check(mp); }
+
+        template <typename MultiPass>
+        inline static void clear_queue(MultiPass& mp) 
+            { Checking::clear_queue(mp); }
+
+        // ownership policy functions are forwarded to the Ownership type
+        template <typename MultiPass>
+        inline static void clone(MultiPass& mp) 
+            { Ownership::clone(mp); }
+
+        template <typename MultiPass>
+        inline static bool release(MultiPass& mp)
+            { return Ownership::release(mp); }
+        
+        template <typename MultiPass>
+        inline static bool is_unique(MultiPass const& mp)
+            { return Ownership::is_unique(mp); }
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // the multi_pass_shared structure is used to combine the shared data items 
+    // of all policies into one single structure
+    ///////////////////////////////////////////////////////////////////////////
+    template<
+        typename T, typename Ownership, typename Checking, typename Input, 
+        typename Storage
+    >
+    struct multi_pass_shared : Ownership, Checking, Input, Storage
+    {
+        explicit multi_pass_shared(T const& input)
+          : Input(input)
+        {}
+    };
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  This is a default implementation of a policy class as required by the
+    //  multi_pass template, combining 4 separate policies into one. Any other
+    //  multi_pass policy class needs to follow the scheme as shown below.
+    template<
+        typename Input, typename Ownership, typename Checking,
+        typename Storage
+    >
+    struct default_policy
+    {
+        typedef Ownership ownership_policy;
+        typedef Checking checking_policy;
+        typedef Input input_policy;
+        typedef Storage storage_policy;
+            
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct unique 
+          : multi_pass_unique<
+                T, typename Ownership::unique, typename Checking::unique,
+                typename Input::BOOST_NESTED_TEMPLATE unique<T>,
+                typename Storage::BOOST_NESTED_TEMPLATE unique<
+                    typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
+            >
+        {
+            typedef typename Ownership::unique ownership_policy;
+            typedef typename Checking::unique checking_policy;
+            typedef typename Input::BOOST_NESTED_TEMPLATE unique<T> 
+                input_policy;
+            typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
+                        typename input_policy::value_type> 
+                storage_policy;
+
+            typedef multi_pass_unique<T, ownership_policy, checking_policy, 
+                    input_policy, storage_policy>
+                unique_base_type;
+
+            unique() {}
+            explicit unique(T const& input) : unique_base_type(input) {}
+        };
+        
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct shared
+          : multi_pass_shared<T, 
+                typename Ownership::shared, typename Checking::shared, 
+                typename Input::BOOST_NESTED_TEMPLATE shared<T>,
+                typename Storage::BOOST_NESTED_TEMPLATE shared<
+                    typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
+            > 
+        {
+            typedef typename Ownership::shared ownership_policy;
+            typedef typename Checking::shared checking_policy;
+            typedef typename Input::BOOST_NESTED_TEMPLATE shared<T> 
+                input_policy;
+            typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
+                    typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> 
+                storage_policy;
+
+            typedef multi_pass_shared<T, ownership_policy, checking_policy, 
+                    input_policy, storage_policy>
+                shared_base_type;
+            
+            explicit shared(T const& input) : shared_base_type(input) {}
+        };
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM)
+#define BOOST_SPIRIT_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class first_owner
+    //  Implementation of an OwnershipPolicy used by multi_pass
+    //  This ownership policy dictates that the first iterator created will
+    //  determine the lifespan of the shared components.  This works well for
+    //  spirit, since no dynamic allocation of iterators is done, and all 
+    //  copies are make on the stack.
+    //
+    //  There is a caveat about using this policy together with the std_deque
+    //  StoragePolicy. Since first_owner always returns false from unique(),
+    //  std_deque will only release the queued data if clear_queue() is called.
+    ///////////////////////////////////////////////////////////////////////////
+    struct first_owner
+    {
+        ///////////////////////////////////////////////////////////////////////
+        struct unique // : detail::default_ownership_policy
+        {
+            unique()
+              : first(true)
+            {}
+
+            unique(unique const&)
+              : first(false)
+            {}
+
+            // return true to indicate deletion of resources
+            template <typename MultiPass>
+            static bool release(MultiPass& mp)
+            {
+                return mp.first;
+            }
+
+            // use swap from default policy
+            // if we're the first, we still remain the first, even if assigned
+            // to, so don't swap first_.  swap is only called from operator=
+
+            template <typename MultiPass>
+            static bool is_unique(MultiPass const& mp) 
+            {
+                return false; // no way to know, so always return false
+            }
+
+        protected:
+            bool first;
+        };
+
+        ////////////////////////////////////////////////////////////////////////
+        struct shared
+        {
+            // no shared data
+        };
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,388 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM)
+#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM
+
+#include <cstdlib>
+#include <iterator>
+#include <cstddef>
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>   // for BOOST_ASSERT
+#include <boost/iterator_adaptors.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//  Make sure we're using a decent version of the Boost.IteratorAdaptors lib
+#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
+    BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
+#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!"
+#endif 
+
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_SPIRIT_ASSERT_FSQ_SIZE                                          \
+    BOOST_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1))       \
+    /**/
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Queue, typename T, typename Pointer>
+    class fsq_iterator
+    :   public boost::iterator_adaptor<
+            fsq_iterator<Queue, T, Pointer>, Pointer, T,
+            std::random_access_iterator_tag
+        >
+    {
+    public:
+        typedef typename Queue::position_type position_type;
+        typedef boost::iterator_adaptor<
+                fsq_iterator<Queue, T, Pointer>, Pointer, T,
+                std::random_access_iterator_tag
+            > base_type;
+
+        fsq_iterator() {}
+        fsq_iterator(position_type const &p_) : p(p_) {}
+        
+        position_type const &get_position() const { return p; }
+        
+    private:
+        friend class boost::iterator_core_access;
+        
+        typename base_type::reference dereference() const
+        {
+            return p.self->m_queue[p.pos];
+        }
+
+        void increment()
+        {
+            ++p.pos;
+            if (p.pos == Queue::MAX_SIZE+1)
+                p.pos = 0;
+        }
+
+        void decrement()
+        {
+            if (p.pos == 0)
+                p.pos = Queue::MAX_SIZE;
+            else
+                --p.pos;
+        }
+
+        template <
+            typename OtherDerived, typename OtherIterator, 
+            typename V, typename C, typename R, typename D
+        >   
+        bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> 
+            const &x) const
+        {
+            position_type const &rhs_pos = 
+                static_cast<OtherDerived const &>(x).get_position();
+            return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
+        }
+
+        template <
+            typename OtherDerived, typename OtherIterator, 
+            typename V, typename C, typename R, typename D
+        >   
+        typename base_type::difference_type distance_to(
+            iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> 
+            const &x) const
+        {
+            typedef typename base_type::difference_type difference_type;
+
+            position_type const &p2 = 
+                static_cast<OtherDerived const &>(x).get_position();
+            std::size_t pos1 = p.pos;
+            std::size_t pos2 = p2.pos;
+
+            //  Undefined behavior if the iterators come from different
+            //  containers
+            BOOST_ASSERT(p.self == p2.self);
+
+            if (pos1 < p.self->m_head)
+                pos1 += Queue::MAX_SIZE;
+            if (pos2 < p2.self->m_head)
+                pos2 += Queue::MAX_SIZE;
+
+            if (pos2 > pos1)
+                return difference_type(pos2 - pos1);
+            else
+                return -difference_type(pos1 - pos2);
+        }
+
+        void advance(typename base_type::difference_type n)
+        {
+            //  Notice that we don't care values of n that can
+            //  wrap around more than one time, since it would
+            //  be undefined behavior anyway (going outside
+            //  the begin/end range). Negative wrapping is a bit
+            //  cumbersome because we don't want to case p.pos
+            //  to signed.
+            if (n < 0)
+            {
+                n = -n;
+                if (p.pos < (std::size_t)n)
+                    p.pos = Queue::MAX_SIZE+1 - (n - p.pos);
+                else
+                    p.pos -= n;
+            }
+            else
+            {
+                p.pos += n;
+                if (p.pos >= Queue::MAX_SIZE+1)
+                    p.pos -= Queue::MAX_SIZE+1;
+            }
+        }
+        
+    private:
+        position_type p;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, std::size_t N>
+    class fixed_size_queue
+    {
+    private:
+        struct position
+        {
+            fixed_size_queue* self;
+            std::size_t pos;
+
+            position() : self(0), pos(0) {}
+
+            // The const_cast here is just to avoid to have two different
+            //  position structures for the const and non-const case.
+            // The const semantic is guaranteed by the iterator itself
+            position(const fixed_size_queue* s, std::size_t p)
+              : self(const_cast<fixed_size_queue*>(s)), pos(p)
+            {}
+        };
+
+    public:
+        // Declare the iterators
+        typedef fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator;
+        typedef 
+            fsq_iterator<fixed_size_queue<T, N>, T const, T const*> 
+        const_iterator;
+        typedef position position_type;
+
+        friend class fsq_iterator<fixed_size_queue<T, N>, T, T*>;
+        friend class fsq_iterator<fixed_size_queue<T, N>, T const, T const*>;
+        
+        fixed_size_queue();
+        fixed_size_queue(const fixed_size_queue& x);
+        fixed_size_queue& operator=(const fixed_size_queue& x);
+        ~fixed_size_queue();
+
+        void push_back(const T& e);
+        void push_front(const T& e);
+        void serve(T& e);
+        void pop_front();
+
+        bool empty() const
+        {
+            return m_size == 0;
+        }
+
+        bool full() const
+        {
+            return m_size == N;
+        }
+
+        iterator begin()
+        {
+            return iterator(position(this, m_head));
+        }
+
+        const_iterator begin() const
+        {
+            return const_iterator(position(this, m_head));
+        }
+
+        iterator end()
+        {
+            return iterator(position(this, m_tail));
+        }
+
+        const_iterator end() const
+        {
+            return const_iterator(position(this, m_tail));
+        }
+
+        std::size_t size() const
+        {
+            return m_size;
+        }
+
+        T& front()
+        {
+            return m_queue[m_head];
+        }
+
+        const T& front() const
+        {
+            return m_queue[m_head];
+        }
+
+    private:
+        // Redefine the template parameters to avoid using partial template
+        //  specialization on the iterator policy to extract N.
+        BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N);
+
+        std::size_t m_head;
+        std::size_t m_tail;
+        std::size_t m_size;
+        T m_queue[N+1];
+    };
+
+    template <typename T, std::size_t N>
+    inline
+    fixed_size_queue<T, N>::fixed_size_queue()
+        : m_head(0)
+        , m_tail(0)
+        , m_size(0)
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+    template <typename T, std::size_t N>
+    inline
+    fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x)
+        : m_head(x.m_head)
+        , m_tail(x.m_tail)
+        , m_size(x.m_size)
+    {
+        copy(x.begin(), x.end(), begin());
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+    template <typename T, std::size_t N>
+    inline fixed_size_queue<T, N>&
+    fixed_size_queue<T, N>::operator=(const fixed_size_queue& x)
+    {
+        if (this != &x)
+        {
+            m_head = x.m_head;
+            m_tail = x.m_tail;
+            m_size = x.m_size;
+            copy(x.begin(), x.end(), begin());
+        }
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+
+        return *this;
+    }
+
+    template <typename T, std::size_t N>
+    inline
+    fixed_size_queue<T, N>::~fixed_size_queue()
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+    template <typename T, std::size_t N>
+    inline void
+    fixed_size_queue<T, N>::push_back(const T& e)
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+
+        BOOST_ASSERT(!full());
+
+        m_queue[m_tail] = e;
+        ++m_size;
+        ++m_tail;
+        if (m_tail == N+1)
+            m_tail = 0;
+
+
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+    template <typename T, std::size_t N>
+    inline void
+    fixed_size_queue<T, N>::push_front(const T& e)
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+
+        BOOST_ASSERT(!full());
+
+        if (m_head == 0)
+            m_head = N;
+        else
+            --m_head;
+
+        m_queue[m_head] = e;
+        ++m_size;
+
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+
+    template <typename T, std::size_t N>
+    inline void
+    fixed_size_queue<T, N>::serve(T& e)
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+
+        e = m_queue[m_head];
+        pop_front();
+    }
+
+
+
+    template <typename T, std::size_t N>
+    inline void
+    fixed_size_queue<T, N>::pop_front()
+    {
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+
+        ++m_head;
+        if (m_head == N+1)
+            m_head = 0;
+        --m_size;
+
+        BOOST_ASSERT(m_size <= N+1);
+        BOOST_SPIRIT_ASSERT_FSQ_SIZE;
+        BOOST_ASSERT(m_head <= N+1);
+        BOOST_ASSERT(m_tail <= N+1);
+    }
+
+}}} 
+
+#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,127 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM)
+#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM
+
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp>
+#include <boost/assert.hpp>
+#include <cstdlib>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class fixed_size_queue
+    //  Implementation of the StoragePolicy used by multi_pass
+    //  fixed_size_queue keeps a circular buffer (implemented by
+    //  boost::spirit::fixed_size_queue class) that is size N+1 and stores N 
+    //  elements.
+    // 
+    //  It is up to the user to ensure that there is enough look ahead for 
+    //  their grammar. Currently there is no way to tell if an iterator is 
+    //  pointing to forgotten data. The leading iterator will put an item in 
+    //  the queue and remove one when it is incremented. No dynamic allocation 
+    //  is done, except on creation of the queue (fixed_size_queue constructor).
+    ///////////////////////////////////////////////////////////////////////////
+    template <std::size_t N>
+    class fixed_size_queue
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Value>
+        class unique : public detail::default_storage_policy
+        {
+        private:
+            typedef detail::fixed_size_queue<Value, N> queue_type;
+
+        protected:
+            unique()
+            {}
+
+            unique(unique const& x)
+              : queuePosition(x.queuePosition)
+            {}
+
+            void swap(inner& x)
+            {
+                spirit::detail::swap(queuePosition, x.queuePosition);
+            }
+
+            //  This is called when the iterator is dereferenced. It's a 
+            //  template method so we can recover the type of the multi_pass 
+            //  iterator and access the m_input data member.
+            template <typename MultiPass>
+            static typename MultiPass::reference 
+            dereference(MultiPass const& mp)
+            {
+                if (mp.queuePosition == mp.shared->queuedElements.end())
+                {
+                    return MultiPass::get_input(mp);
+                }
+                else
+                {
+                    return *mp.queuePosition;
+                }
+            }
+
+            //  This is called when the iterator is incremented. It's a 
+            //  template method so we can recover the type of the multi_pass 
+            //  iterator and access the m_input data member.
+            template <typename MultiPass>
+            static void increment(MultiPass& mp)
+            {
+                if (mp.queuePosition == mp.shared->queuedElements.end())
+                {
+                    // don't let the queue get larger than N
+                    if (mp.shared->queuedElements.size() >= N)
+                        mp.shared->queuedElements.pop_front();
+
+                    mp.shared->queuedElements.push_back(MultiPass::get_input(mp));
+                    MultiPass::advance_input(mp);
+                }
+                ++mp.queuePosition;
+            }
+
+            // clear_queue is a no-op
+
+            // called to determine whether the iterator is an eof iterator
+            template <typename MultiPass>
+            static bool is_eof(MultiPass const& mp)
+            {
+                return mp.queuePosition == mp.shared->queuedElements.end() &&
+                       MultiPass::input_at_eof(mp);
+            }
+
+            // called by operator==
+            template <typename MultiPass>
+            static bool equal_to(MultiPass const& mp, MultiPass const& x) 
+            {
+                return queuePosition == x.queuePosition;
+            }
+
+            // called by operator<
+            template <typename MultiPass>
+            static bool less_than(MultiPass const& mp, MultiPass const& x)
+            {
+                return queuePosition < x.queuePosition;
+            }
+
+        protected:
+            mutable typename queue_type::iterator queuePosition;
+        }; 
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Value>
+        struct shared
+        {
+            typedef detail::fixed_size_queue<Value, N> queue_type;
+            queue_type queuedElements;
+        }; 
+    }; 
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,106 @@
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M)
+#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    namespace is_valid_test_
+    {
+        template <typename Token>
+        inline bool token_is_valid(Token const&)
+        {
+            return true;
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  class functor_input
+    //  Implementation of the InputPolicy used by multi_pass
+    //  functor_input gets tokens from a functor
+    // 
+    //  Note: the functor must have a typedef for result_type
+    //        It also must have a static variable of type result_type defined 
+    //        to represent EOF that is called eof.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    struct functor_input
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Functor>
+        class unique : public detail::default_input_policy
+        {
+        private:
+            typedef typename Functor::result_type result_type;
+
+        protected:
+            unique() {}
+            explicit unique(Functor const& x) : ftor(x) {}
+
+            void swap(unique& x)
+            {
+                spirit::detail::swap(ftor, x.ftor);
+            }
+
+        public:
+            typedef result_type value_type;
+            typedef std::ptrdiff_t difference_type;
+            typedef std::ptrdiff_t distance_type;
+            typedef result_type* pointer;
+            typedef result_type& reference;
+
+        public:
+            // get the next token
+            template <typename MultiPass>
+            static void advance_input(MultiPass& mp, value_type& t)
+            {
+                // if mp.shared is NULL then this instance of the multi_pass 
+                // represents a end iterator, so no advance functionality is 
+                // needed
+                if (0 != mp.shared) 
+                    t = mp.ftor();
+            }
+
+            // test, whether we reached the end of the underlying stream
+            template <typename MultiPass>
+            static bool input_at_eof(MultiPass const& mp, value_type const& t) 
+            {
+                return t == mp.ftor.eof;
+            }
+
+            template <typename MultiPass>
+            static bool input_is_valid(MultiPass const& mp, value_type const& t) 
+            {
+                using namespace is_valid_test_;
+                return token_is_valid(t);
+            }
+
+            Functor& get_functor() const
+            {
+                return ftor;
+            }
+
+        protected:
+            mutable Functor ftor;
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Functor>
+        struct shared
+        {
+            explicit shared(Functor const& x) {}
+
+            // no shared data elements
+        };
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,108 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM)
+#define BOOST_SPIRIT_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
+#include <boost/assert.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    namespace is_valid_test_
+    {
+        template <typename Token>
+        inline bool token_is_valid(Token const&)
+        {
+            return true;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  class input_iterator
+    //  Implementation of the InputPolicy used by multi_pass
+    // 
+    //  The input_iterator encapsulates an input iterator of type T
+    ///////////////////////////////////////////////////////////////////////////
+    struct input_iterator
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        class unique : public detail::default_input_policy
+        {
+        private:
+            typedef
+                typename boost::detail::iterator_traits<T>::value_type
+            result_type;
+
+        public:
+            typedef
+                typename boost::detail::iterator_traits<T>::difference_type
+            difference_type;
+            typedef
+                typename boost::detail::iterator_traits<T>::distance_type
+            distance_type;
+            typedef
+                typename boost::detail::iterator_traits<T>::pointer
+            pointer;
+            typedef
+                typename boost::detail::iterator_traits<T>::reference
+            reference;
+            typedef result_type value_type;
+
+        protected:
+            unique() {}
+            explicit unique(T x) : input(x) {}
+
+            void swap(inner& x)
+            {
+                spirit::detail::swap(input, x.input);
+            }
+
+        public:
+            template <typename MultiPass>
+            static void advance_input(MultiPass& mp, value_type& t)
+            {
+                // if mp.shared is NULL then this instance of the multi_pass 
+                // represents a end iterator, so no advance functionality is 
+                // needed
+                if (0 != mp.shared) 
+                    t = *++mp.input;
+            }
+
+            // test, whether we reached the end of the underlying stream
+            template <typename MultiPass>
+            static bool input_at_eof(MultiPass const& mp, value_type const& t) 
+            {
+                return mp.input == T();
+            }
+
+            template <typename MultiPass>
+            static bool input_is_valid(MultiPass const& mp, value_type const& t) 
+            {
+                using namespace is_valid_test_;
+                return token_is_valid(t);
+            }
+
+        protected:
+            T input;
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct shared
+        {
+            explicit shared(T x) {}
+
+            // no shared data elements
+        };
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,79 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM)
+#define BOOST_SPIRIT_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////////
+    //  class lex_input
+    //  Implementation of the InputPolicy used by multi_pass
+    // 
+    //  The lex_input class gets tokens (integers) from yylex()
+    ///////////////////////////////////////////////////////////////////////////
+    struct lex_input
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        class unique : public detail::default_input_policy
+        {
+        public:
+            typedef int value_type;
+            typedef std::ptrdiff_t difference_type;
+            typedef std::ptrdiff_t distance_type;
+            typedef int* pointer;
+            typedef int& reference;
+
+        protected:
+            unique() {}
+            explicit unique(T x) {}
+
+        public:
+            template <typename MultiPass>
+            static void advance_input(MultiPass& mp, value_type& t)
+            {
+                // if mp.shared is NULL then this instance of the multi_pass 
+                // represents a end iterator, so no advance functionality is 
+                // needed
+                if (0 != mp.shared) 
+                {
+                    extern int yylex();
+                    t = yylex();
+                }
+            }
+
+            // test, whether we reached the end of the underlying stream
+            template <typename MultiPass>
+            static bool input_at_eof(MultiPass const& mp, value_type const& t) 
+            {
+                return 0 == t;
+            }
+
+            template <typename MultiPass>
+            static bool input_is_valid(MultiPass const& mp, value_type const& t) 
+            {
+                return -1 != t;
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename T>
+        struct shared
+        {
+            explicit shared(T x) {}
+
+            // no shared data elements
+        };
+    };
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,136 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM)
+#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/iterator.hpp>
+#include <boost/mpl/bool.hpp>
+#include <iterator>
+#include <algorithm> 
+
+namespace boost { namespace spirit { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    inline void swap(T& t1, T& t2)
+    {
+        using std::swap;
+        using boost::spirit::swap;
+        swap(t1, t2);
+    }
+    
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+    ///////////////////////////////////////////////////////////////////////////
+    //  Meta-function to generate a std::iterator<> base class for multi_pass. 
+    //  This is used mainly to improve conformance of compilers not supporting 
+    //  PTS and thus relying on inheritance to recognize an iterator.
+    //
+    //  We are using boost::iterator<> because it offers an automatic 
+    //  workaround for broken std::iterator<> implementations.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename InputPolicy>
+    struct iterator_base_creator
+    {
+        typedef typename InputPolicy::BOOST_NESTED_TEMPLATE unique<T> input_type;
+
+        typedef boost::iterator <
+            std::forward_iterator_tag,
+            typename input_type::value_type,
+            typename input_type::difference_type,
+            typename input_type::pointer,
+            typename input_type::reference
+        > type;
+    };
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Default implementations of the different policies to be used with a 
+    //  multi_pass iterator
+    ///////////////////////////////////////////////////////////////////////////
+    struct default_input_policy
+    {
+        default_input_policy() {}
+        
+        template <typename Functor>
+        default_input_policy(Functor const& x) {}
+        
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp) {}
+        
+        void swap(default_input_policy& /*x*/) {}
+        
+        template <typename MultiPass, typename TokenType>
+        static TokenType& advance_input(MultiPass& mp, TokenType& curtok);
+
+        template <typename MultiPass, typename TokenType>
+        static bool input_at_eof(MultiPass const& mp, TokenType& curtok);
+
+        template <typename MultiPass, typename TokenType>
+        static bool input_is_valid(MultiPass& mp, TokenType& curtok);
+    };
+    
+    struct default_ownership_policy
+    {
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp) {}
+
+        void swap(default_ownership_policy&) {}
+
+        template <typename MultiPass>
+        static void clone(MultiPass& mp) {}
+
+        template <typename MultiPass>
+        static bool release(MultiPass& mp);
+        
+        template <typename MultiPass>
+        static bool is_unique(MultiPass const& mp);
+    };
+    
+    struct default_storage_policy
+    {
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp) {}
+
+        void swap(default_storage_policy&) {}
+
+        template <typename MultiPass>
+        static typename MultiPass::reference dereference(MultiPass const& mp);
+        
+        template <typename MultiPass>
+        static void increment(MultiPass& mp) {}
+        
+        template <typename MultiPass>
+        static void clear_queue(MultiPass& mp) {}
+
+        template <typename MultiPass>
+        static bool is_eof(MultiPass const& mp);
+
+        template <typename MultiPass>
+        static bool equal_to(MultiPass const& mp, MultiPass const& x);
+
+        template <typename MultiPass>
+        static bool less_than(MultiPass const& mp, MultiPass const& x);
+    };
+    
+    struct default_checking_policy
+    {
+        template <typename MultiPass>
+        static void destroy(MultiPass& mp) {}
+
+        void swap(default_checking_policy&) {}
+
+        template <typename MultiPass>
+        static void check(MultiPass const&) {}
+
+        template <typename MultiPass>
+        static void clear_queue(MultiPass&) {}
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/no_check_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/no_check_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,44 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM)
+#define BOOST_SPIRIT_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class no_check
+    //  Implementation of the CheckingPolicy used by multi_pass
+    //  It does not do anything :-)
+    ///////////////////////////////////////////////////////////////////////////
+    struct no_check
+    {
+        ///////////////////////////////////////////////////////////////////////
+        struct unique // : public detail::default_checking_policy
+        {
+            void swap(unique&) {}
+
+            template <typename MultiPass>
+            static void check(MultiPass const&) {}
+
+            template <typename MultiPass>
+            static void clear_queue(MultiPass&) {}
+
+            template <typename MultiPass>
+            static void destroy(MultiPass& mp) {}
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        struct shared 
+        {};
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,72 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM)
+#define BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <cstdlib>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class ref_counted
+    //  Implementation of an OwnershipPolicy used by multi_pass.
+    //
+    //  Implementation modified from RefCounted class from the Loki library by
+    //  Andrei Alexandrescu.
+    ///////////////////////////////////////////////////////////////////////////
+    struct ref_counted
+    {
+        ///////////////////////////////////////////////////////////////////////
+        struct unique // : detail::default_ownership_policy
+        {
+            void swap(unique& x) {}
+
+            // clone is called when a copy of the iterator is made, so 
+            // increment the ref-count.
+            template <typename MultiPass>
+            static void clone(MultiPass& mp)
+            {
+                if (0 != mp.shared)
+                    ++mp.shared->count;
+            }
+
+            // called when a copy is deleted. Decrement the ref-count. Return
+            // value of true indicates that the last copy has been released.
+            template <typename MultiPass>
+            static bool release(MultiPass& mp)
+            {
+                return 0 != mp.shared && 0 == --mp.shared->count;
+            }
+
+            // returns true if there is only one iterator in existence.
+            // std_deque StoragePolicy will free it's buffered data if this
+            // returns true.
+            template <typename MultiPass>
+            static bool is_unique(MultiPass const& mp) 
+            {
+                return 0 == mp.shared || 1 == mp.shared->count;
+            }
+
+            template <typename MultiPass>
+            static void destroy(MultiPass& mp) 
+            {}
+        };
+
+        ////////////////////////////////////////////////////////////////////////
+        struct shared
+        {
+            shared() : count(1) {}
+            std::size_t count;
+        };
+
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,173 @@
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM)
+#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/assert.hpp>
+#include <boost/type_traits/is_empty.hpp>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    namespace is_valid_test_
+    {
+        template <typename Token>
+        inline bool token_is_valid(Token const&)
+        {
+            return true;
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //  class split_functor_input
+    //  Implementation of the InputPolicy used by multi_pass
+    //  split_functor_input gets tokens from a functor
+    // 
+    //  This policy should be used when the functor hold two parts of data: a
+    //  unique part (unique for each instance of the iterator) and a shared 
+    //  part (to be shared between the different copies of the same iterator).
+    //  Using this policy allows to merge the shared part of the functor with 
+    //  the shared part of the iterator data, saving one pointer and one 
+    //  allocation per iterator instance.
+    //
+    //  The Functor template parameter of this policy is expected to be a 
+    //  std::pair<unique, shared>, where 'unique' and 'shared' represent the
+    //  respective parts of the functor itself.
+    //
+    //  Note: the unique part of the functor must have a typedef for result_type
+    //        It also must have a static variable of type result_type defined 
+    //        to represent EOF that is called eof.
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    struct split_functor_input
+    {
+        ///////////////////////////////////////////////////////////////////////
+        template <
+            typename Functor, 
+            bool FunctorIsEmpty = is_empty<typename Functor::first_type>::value
+        >
+        class unique;
+        
+        // the unique part of the functor is empty, do not include the functor 
+        // at all to avoid unnecessary padding bytes to be included into the 
+        // generated structure
+        template <typename Functor>
+        class unique<Functor, true> // : public detail::default_input_policy
+        {
+        protected:
+            typedef typename Functor::first_type functor_type;
+            typedef typename functor_type::result_type result_type;
+
+        public:
+            typedef result_type value_type;
+            typedef std::ptrdiff_t difference_type;
+            typedef std::ptrdiff_t distance_type;
+            typedef result_type* pointer;
+            typedef result_type& reference;
+
+        protected:
+            unique() {}
+            explicit unique(Functor const& x) {}
+
+        public:
+            void swap(unique& x) {}
+
+            // get the next token
+            template <typename MultiPass>
+            static value_type& advance_input(MultiPass& mp, value_type& t)
+            {
+                // passing the current token instance as a parameter helps
+                // generating better code if compared to assigning the 
+                // result of the functor to this instance
+                return functor_type::get_next(mp, t);
+            }
+
+            // test, whether we reached the end of the underlying stream
+            template <typename MultiPass>
+            static bool input_at_eof(MultiPass const&, value_type const& t) 
+            {
+                return t == functor_type::eof;
+            }
+
+            template <typename MultiPass>
+            static bool input_is_valid(MultiPass const&, value_type const& t) 
+            {
+                using namespace is_valid_test_;
+                return token_is_valid(t);
+            }
+
+            template <typename MultiPass>
+            static void destroy(MultiPass& mp) 
+            {
+                functor_type::destroy(mp.shared);
+            }
+        };
+        
+        // the unique part of the functor is non-empty
+        template <typename Functor>
+        class unique<Functor, false> : public unique<Functor, true>
+        {
+        protected:
+            typedef typename Functor::first_type functor_type;
+            typedef typename functor_type::result_type result_type;
+
+        protected:
+            unique() {}
+            explicit unique(Functor const& x) : ftor(x.first) {}
+
+            void swap(unique& x)
+            {
+                spirit::detail::swap(ftor, x.ftor);
+            }
+
+        public:
+            typedef result_type value_type;
+            typedef std::ptrdiff_t difference_type;
+            typedef std::ptrdiff_t distance_type;
+            typedef result_type* pointer;
+            typedef result_type& reference;
+
+        public:
+            // get the next token
+            template <typename MultiPass>
+            static value_type& advance_input(MultiPass& mp, value_type& t)
+            {
+                // passing the current token instance as a parameter helps
+                // generating better code if compared to assigning the 
+                // result of the functor to this instance
+                return ftor.get_next(mp, t);
+            }
+
+            // test, whether we reached the end of the underlying stream
+            template <typename MultiPass>
+            static bool input_at_eof(MultiPass const& mp, value_type const& t) 
+            {
+                return t == mp.ftor.eof;
+            }
+
+            typename Functor::first_type& get_functor() const
+            {
+                return ftor;
+            }
+
+        protected:
+            mutable functor_type ftor;
+        };
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Functor>
+        struct shared
+        {
+            explicit shared(Functor const& x) : ftor(x.second) {}
+
+            mutable typename Functor::second_type ftor;
+        };
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,170 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
+#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/assert.hpp>
+#include <vector>
+
+namespace boost { namespace spirit { namespace multi_pass_policies
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  class split_std_deque
+    //
+    //  Implementation of the StoragePolicy used by multi_pass
+    //  This stores all data in a std::vector (despite its name), and keeps an 
+    //  offset to the current position. It stores all the data unless there is 
+    //  only one iterator using the queue.
+    // 
+    ///////////////////////////////////////////////////////////////////////////
+    struct split_std_deque
+    {
+        enum { threshold = 1000 };
+        
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Value>
+        class unique //: public detail::default_storage_policy
+        {
+        private:
+            typedef std::vector<Value> queue_type;
+
+        protected:
+            unique()
+              : queued_position(0)
+            {}
+
+            unique(unique const& x)
+              : queued_position(x.queued_position)
+            {}
+
+            void swap(unique& x)
+            {
+                spirit::detail::swap(queued_position, x.queued_position);
+            }
+
+            // This is called when the iterator is dereferenced.  It's a 
+            // template method so we can recover the type of the multi_pass 
+            // iterator and call advance_input and input_is_valid.
+            template <typename MultiPass>
+            static typename MultiPass::reference 
+            dereference(MultiPass const& mp)
+            {
+                queue_type& queue = mp.shared->queued_elements;
+                if (0 == mp.queued_position) 
+                {
+                    if (queue.empty())
+                    {
+                        queue.push_back(Value());
+                        return MultiPass::advance_input(mp, queue[mp.queued_position++]);
+                    }
+                    return queue[mp.queued_position++];
+                }
+                else if (!MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
+                {
+                    MultiPass::advance_input(mp, queue[mp.queued_position-1]);
+                }
+                return queue[mp.queued_position-1];
+            }
+
+            // This is called when the iterator is incremented. It's a template
+            // method so we can recover the type of the multi_pass iterator
+            // and call is_unique and advance_input.
+            template <typename MultiPass>
+            static void increment(MultiPass& mp)
+            {
+                queue_type& queue = mp.shared->queued_elements;
+                typename queue_type::size_type size = queue.size();
+                BOOST_ASSERT(0 != size && mp.queued_position <= size);
+                if (mp.queued_position == size)
+                {
+                    // check if this is the only iterator
+                    if (size >= threshold && MultiPass::is_unique(mp))
+                    {
+                        // free up the memory used by the queue. we avoid 
+                        // clearing the queue on every increment, though, 
+                        // because this would be too time consuming
+                        queue.clear();
+                        queue.reserve(threshold);
+                        mp.queued_position = 0;
+                        
+                        // create a new entry in the queue and initialize 
+                        // it from the input
+                        queue.push_back(Value());
+                        MultiPass::advance_input(mp, queue[mp.queued_position++]);
+                    }
+                    else
+                    {
+                        // create a new entry in the queue and initialize 
+                        // it from the input
+                        queue.push_back(Value());
+                        MultiPass::advance_input(mp, queue[mp.queued_position++]);
+                    }
+                }
+                else
+                {
+                    ++mp.queued_position;
+                }
+            }
+
+            // called to forcibly clear the queue
+            template <typename MultiPass>
+            static void clear_queue(MultiPass& mp)
+            {
+                mp.shared->queued_elements.clear();
+                mp.queued_position = 0;
+            }
+
+            // called to determine whether the iterator is an eof iterator
+            template <typename MultiPass>
+            static bool is_eof(MultiPass const& mp)
+            {
+                queue_type& queue = mp.shared->queued_elements;
+                return 0 != mp.queued_position && 
+                    mp.queued_position == queue.size() && 
+                    MultiPass::input_at_eof(mp, queue[mp.queued_position-1]);
+            }
+
+            // called by operator==
+            template <typename MultiPass>
+            static bool equal_to(MultiPass const& mp, MultiPass const& x) 
+            {
+                return mp.queued_position == x.queued_position;
+            }
+
+            // called by operator<
+            template <typename MultiPass>
+            static bool less_than(MultiPass const& mp, MultiPass const& x)
+            {
+                return mp.queued_position < x.queued_position;
+            }
+            
+            template <typename MultiPass>
+            static void destroy(MultiPass& mp) 
+            {}
+
+        protected:
+            mutable typename queue_type::size_type queued_position;
+        }; 
+
+        ///////////////////////////////////////////////////////////////////////
+        template <typename Value>
+        struct shared
+        {
+            shared() { queued_elements.reserve(threshold); }
+            
+            typedef std::vector<Value> queue_type;
+            queue_type queued_elements;
+        }; 
+
+    }; // split_std_deque
+
+}}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/iterators/look_ahead.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/look_ahead.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,62 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+//  http://spirit.sourceforge.net/
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_LOOK_AHEAD_MAR_16_2007_1253PM)
+#define BOOST_SPIRIT_ITERATOR_LOOK_AHEAD_MAR_16_2007_1253PM
+
+#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/first_owner_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp>
+#include <boost/spirit/home/support/iterators/multi_pass.hpp>
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  this could be a template typedef, since such a thing doesn't
+    //  exist in C++, we'll use inheritance to accomplish the same thing.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, std::size_t N>
+    class look_ahead :
+        public multi_pass<
+            T,
+            multi_pass_policies::input_iterator,
+            multi_pass_policies::first_owner,
+            multi_pass_policies::no_check,
+            multi_pass_policies::fixed_size_queue<N> 
+        >
+    {
+    private:
+        typedef multi_pass<
+            T,
+            multi_pass_policies::input_iterator,
+            multi_pass_policies::first_owner,
+            multi_pass_policies::no_check,
+            multi_pass_policies::fixed_size_queue<N> > 
+        base_type;
+            
+    public:
+        look_ahead()
+          : base_type() {}
+
+        explicit look_ahead(T x)
+          : base_type(x) {}
+
+        look_ahead(look_ahead const& x)
+          : base_type(x) {}
+
+#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+        look_ahead(int)         // workaround for a bug in the library
+          : base_type() {}      // shipped with gcc 3.1
+#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+
+    // default generated operators destructor and assignment operator are ok.
+    };
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/iterators/multi_pass.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/multi_pass.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,205 @@
+//  Copyright (c) 2001, Daniel C. Nuffer
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+//  http://spirit.sourceforge.net/
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
+#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+#include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
+#include <boost/limits.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // The default multi_pass instantiation uses a ref-counted std_deque scheme.
+    ///////////////////////////////////////////////////////////////////////////
+    template<typename T, typename Policies>
+    class multi_pass 
+      : public Policies::BOOST_NESTED_TEMPLATE unique<T>
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+      , typename iterator_base_creator<T, typename Policies::input_policy>::type
+#endif
+    {
+    private:
+        // unique and shared data types
+        typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T> 
+            policies_base_type;
+        typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T> 
+            shared_data_type;
+                
+        // define the types the standard embedded iterator typedefs are taken 
+        // from
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+        typedef typename iterator_base_creator<Input, T>::type iterator_type;
+#else
+        typedef typename policies_base_type::input_policy iterator_type;
+#endif
+
+    public:
+        // standard iterator typedefs
+        typedef std::forward_iterator_tag iterator_category;
+        typedef typename iterator_type::value_type value_type;
+        typedef typename iterator_type::difference_type difference_type;
+        typedef typename iterator_type::distance_type distance_type;
+        typedef typename iterator_type::reference reference;
+        typedef typename iterator_type::pointer pointer;
+
+        multi_pass()
+          : shared(0)
+        {}
+        
+        explicit multi_pass(T input)
+          : shared(new shared_data_type(input)), policies_base_type(input)
+        {}
+
+#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+        // The standard library shipped with gcc-3.1 has a bug in
+        // bits/basic_string.tcc. It tries to use iter::iter(0) to
+        // construct an iterator. Ironically, this  happens in sanity
+        // checking code that isn't required by the standard.
+        // The workaround is to provide an additional constructor that
+        // ignores its int argument and behaves like the default constructor.
+        multi_pass(int)
+          : shared(0)
+        {}
+#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+
+        ~multi_pass()
+        {
+            if (policies_base_type::release(*this)) {
+                policies_base_type::destroy(*this);
+                delete shared;
+            }
+        }
+
+        multi_pass(multi_pass const& x)
+          : shared(x.shared), policies_base_type(x)
+        {
+            policies_base_type::clone(*this);
+        }
+        
+        multi_pass& operator=(multi_pass const& x)
+        {
+            if (this != &x) {
+                multi_pass temp(x);
+                temp.swap(*this);
+            }
+            return *this;
+        }
+
+        void swap(multi_pass& x)
+        {
+            spirit::detail::swap(shared, x.shared);
+            this->policies_base_type::swap(x);
+        }
+
+        reference operator*() const
+        {
+            policies_base_type::check(*this);
+            return policies_base_type::dereference(*this);
+        }
+        pointer operator->() const
+        {
+            return &(operator*());
+        }
+
+        multi_pass& operator++()
+        {
+            policies_base_type::check(*this);
+            policies_base_type::increment(*this);
+            return *this;
+        }
+        multi_pass operator++(int)
+        {
+            multi_pass tmp(*this);
+            ++*this;
+            return tmp;
+        }
+
+        void clear_queue()
+        {
+            policies_base_type::clear_queue(*this);
+        }
+
+        bool operator==(multi_pass const& y) const
+        {
+            if (is_eof())
+                return y.is_eof();
+            if (y.is_eof())
+                return false;
+                
+            return policies_base_type::equal_to(*this, y);
+        }
+        bool operator<(multi_pass const& y) const
+        {
+            return policies_base_type::less_than(*this, y);
+        }
+
+    private: // helper functions
+        bool is_eof() const
+        {
+            return (0 == shared) || policies_base_type::is_eof(*this);
+        }
+        
+    public:
+        shared_data_type *shared;
+    };
+
+
+    template <typename T, typename Policies>
+    inline bool 
+    operator!=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
+    {
+        return !(x == y);
+    }
+
+    template <typename T, typename Policies>
+    inline bool 
+    operator>(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
+    {
+        return y < x;
+    }
+
+    template <typename T, typename Policies>
+    inline bool 
+    operator>=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
+    {
+        return !(x < y);
+    }
+
+    template <typename T, typename Policies>
+    inline bool 
+    operator<=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
+    {
+        return !(y < x);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  Generator function
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Policies, typename T>
+    inline multi_pass<T, Policies>
+    make_multi_pass(T i)
+    {
+        return multi_pass<T, Policies>(i);
+    }
+
+    template <typename T, typename Policies>
+    inline void 
+    swap(multi_pass<T, Policies> &x,
+         multi_pass<T, Policies> &y)
+    {
+        x.swap(y);
+    }
+
+}} // namespace boost::spirit
+
+#endif 
+
+
Added: trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,51 @@
+/*=============================================================================
+    Copyright (c) 2007 Tobias Schwinger
+    http://spirit.sourceforge.net/
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_FWD_HPP)
+#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_FWD_HPP
+
+#include <cstddef>
+
+namespace boost { namespace spirit {
+
+    namespace multi_pass_policies
+    {
+        // input policies
+        struct input_iterator;
+        struct lex_input;
+        struct functor_input;
+        struct split_functor_input;
+        
+        // ownership policies
+        struct ref_counted;
+        struct first_owner;
+        
+        // checking policies
+        class illegal_backtracking;
+        struct buf_id_check;
+        struct no_check;
+        
+        // storage policies
+        struct std_deque;
+        template<std::size_t N> struct fixed_size_queue;
+    }
+
+    template <typename T, typename Policies>
+    class multi_pass;
+
+    template <typename T, typename Policies>
+    void swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y);
+
+    namespace detail 
+    {
+        template <typename T> void swap(T& t1, T& t2);
+    }
+    
+}} // namespace boost::spirit
+
+#endif
+
Added: trunk/boost/spirit/home/support/meta_grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/meta_grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_META_GRAMMAR_JAN_29_2007_0933AM)
+#define BOOST_SPIRIT_META_GRAMMAR_JAN_29_2007_0933AM
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_rules.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
+
+#endif
+
+
Added: trunk/boost/spirit/home/support/meta_grammar/basic_rules.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/meta_grammar/basic_rules.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,317 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_BASIC_RULES_JAN_14_2007_1222PM)
+#define BOOST_SPIRIT_BASIC_RULES_JAN_14_2007_1222PM
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+#include <boost/mpl/identity.hpp>
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    namespace detail
+    {
+        template <typename Director>
+        struct director_identity
+        {
+            template <typename>
+            struct apply : mpl::identity<Director> {};
+        };
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes an empty (the terminal is not saved in
+    //  the elements tuple) terminal spirit::component given a domain,
+    //  a proto-tag and a director.  Example:
+    //
+    //      a
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Tag, typename Director>
+    struct empty_terminal_rule
+    : compose_empty<
+            proto::terminal<Tag>
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a non-empty (the terminal is saved in
+    //  the elements tuple) terminal spirit::component given a domain,
+    //  a proto-tag and a director.  Example:
+    //
+    //      a
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain, typename Tag, typename Director>
+    struct terminal_rule
+    : compose_single<
+            proto::terminal<Tag>
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 1-element spirit::component given a
+    //  domain, a proto-tag and a director. No folding takes place. Example:
+    //
+    //      +a
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag, typename Director
+      , typename SubjectGrammar = proto::_
+    >
+    struct unary_rule
+    : compose_single<
+            proto::unary_expr<
+                Tag
+              , SubjectGrammar
+            >
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 2-element spirit::component given a
+    //  domain, a proto-tag and a director. No folding takes place. Example:
+    //
+    //      a - b
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag, typename Director
+      , typename LeftGrammar = proto::_, typename RightGrammar = proto::_
+    >
+    struct binary_rule
+    : compose_double<
+            proto::binary_expr<
+                Tag
+              , LeftGrammar
+              , RightGrammar
+            >
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 3-element spirit::component given a
+    //  domain, a proto-tag and a director. No folding takes place. Example:
+    //
+    //      if_else(cond_expr,true_exp,false_expr)
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    template <
+    typename Domain, typename Tag, typename Director
+    , typename Grammar0 = proto::_, typename Grammar1 = proto::_, typename Grammar2 = proto::_
+    >
+    struct ternary_rule
+    : compose_triple<
+            proto::nary_expr<
+                Tag
+              , Grammar0
+              , Grammar1
+              , Grammar2
+            >
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 1-element spirit::component from a
+    //  binary expression. Only the RHS is stored.
+    //
+    //      a[b]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag, typename Director
+      , typename LeftGrammar = proto::_, typename RightGrammar = proto::_
+    >
+    struct binary_rule_rhs
+    : compose_right<
+            proto::binary_expr<
+                Tag
+              , LeftGrammar
+              , RightGrammar
+            >
+          , Domain
+          , detail::director_identity<Director>
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a multi-element spirit::component given a
+    //  domain, a proto-tag and a director. All like-operators are folded
+    //  into one. Example:
+    //
+    //      a | b | c
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag, typename Director
+      , typename Grammar = proto::_
+    >
+    struct binary_rule_flat
+    : compose_list<
+            proto::when<
+                proto::binary_expr<Tag, Grammar, Grammar>
+              , proto::reverse_fold_tree<
+                    proto::_
+                  , fusion::nil()
+                  , fusion::cons<Grammar, proto::_state>(Grammar, proto::_state)
+                >
+            >
+          , Domain
+          , Director
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 1-element function spirit::component
+    //  given a domain, a proto-tag and a director. Example:
+    //
+    //      f(a)
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag
+      , typename Director, typename ArgGrammar = proto::_>
+    struct function1_rule
+    : compose_function1<
+            proto::function<proto::terminal<Tag>, ArgGrammar>
+          , Domain
+          , Director
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 2-element function spirit::component
+    //  given a domain, a proto-tag and a director. Example:
+    //
+    //      f(a, b)
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag
+      , typename Director, typename ArgGrammar = proto::_>
+    struct function2_rule
+    : compose_function2<
+            proto::function<
+                proto::terminal<Tag>
+              , ArgGrammar
+              , ArgGrammar
+            >
+          , Domain
+          , Director
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule for directives. The directive (terminal) tag
+    //  is pushed into the modifier state (the Visitor). Example:
+    //
+    //      directive[a]
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Tag, typename SubjectGrammar = proto::_>
+    struct deep_directive_meta_grammar
+    : meta_grammar::compose_deep_directive<
+            proto::when<
+                proto::subscript<proto::terminal<Tag>, SubjectGrammar>
+              , proto::call<SubjectGrammar(proto::_right)>
+            >
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 2-element spirit::component given a
+    //  domain, a proto-tag, a director, and an embedded grammar. 
+    //  Example:
+    //
+    //      directive[p]
+    //
+    //  The difference to deep_directive_meta_grammar is that it stores both
+    //  parts of the expression without modifying the modifier state
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag,
+        typename Director, typename EmbeddedGrammar = proto::_
+    >
+    struct subscript_rule
+      : compose_subscript<
+            proto::binary_expr<
+                proto::tag::subscript, 
+                proto::terminal<Tag>, 
+                EmbeddedGrammar
+            >,
+            Domain,
+            Director
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 2-element spirit::component given a
+    //  domain, a proto-tag, a director, an argument and an embedded grammar. 
+    //  Example:
+    //
+    //      directive(a)[p]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag,
+        typename Director, typename ArgGrammar = proto::_, 
+        typename EmbeddedGrammar = proto::_
+    >
+    struct subscript_function1_rule
+      : compose_subscript_function1<
+            proto::binary_expr<
+                proto::tag::subscript,
+                proto::function<proto::terminal<Tag>, ArgGrammar>,
+                EmbeddedGrammar
+            >,
+            Domain,
+            Director
+        >
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto rule that composes a 3-element spirit::component given a
+    //  domain, a proto-tag, a director, two arguments and an embedded grammar. 
+    //  Example:
+    //
+    //      directive(a, b)[p]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        typename Domain, typename Tag,
+        typename Director, typename Arg1Grammar = proto::_, 
+        typename Arg2Grammar = proto::_, typename EmbeddedGrammar = proto::_
+    >
+    struct subscript_function2_rule
+      : compose_subscript_function2<
+            proto::binary_expr<
+                proto::tag::subscript,
+                proto::function<proto::terminal<Tag>, Arg1Grammar, Arg2Grammar>,
+                EmbeddedGrammar
+            >,
+            Domain,
+            Director
+        >
+    {};
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/meta_grammar/basic_transforms.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/meta_grammar/basic_transforms.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,785 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_BASIC_TRANSFORMS_JAN_14_2007_1222PM)
+#define BOOST_SPIRIT_BASIC_TRANSFORMS_JAN_14_2007_1222PM
+
+#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/modifier.hpp>
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+
+#include <boost/fusion/include/cons.hpp>
+#include <boost/fusion/include/list.hpp>
+#include <boost/fusion/include/make_cons.hpp>
+#include <boost/fusion/include/make_list.hpp>
+
+#include <boost/mpl/apply.hpp>
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating empty component meta descriptions
+    //  (proto expressions) usable for defining meta grammars. Additionally,
+    //  this is used to make the corresponding spirit component.
+    //
+    //    Grammar:   the proto grammar to use as the base for this component
+    //               meta description (i.e.: proto::terminal<Tag>)
+    //    Domain:    the domain this proto transform is defined for
+    //               (i.e.: qi::domain)
+    //    DirectorF: the director is the real component form the specified
+    //               domain (i.e.: any_char)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_empty : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename proto::result_of::arg<Expr>::type arg_type;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply1<DirectorF, arg_type>::type
+                  , fusion::nil
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const&, State const&, Visitor&) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(fusion::nil());
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating single-element component meta
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //
+    //    Grammar:   the proto grammar to use as the base for this component
+    //               meta description (i.e.: proto::unary_expr<Tag, ...>)
+    //    Domain:    the domain this proto transform is defined for
+    //               (i.e.: qi::domain)
+    //    DirectorF: the director is the real component from the specified
+    //               domain (i.e.: negated_char_parser<...>)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_single : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename Grammar::template result<void(Expr, State, Visitor)>::type
+                >::type
+            arg_type;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply1<DirectorF, arg_type>::type
+                  , typename fusion::result_of::make_cons<arg_type>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(
+                fusion::make_cons(
+                   proto::arg(Grammar()(expr, state, visitor))
+                )
+            );
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating double-element component meta
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //
+    //    Grammar:   the proto grammar to use as the base for this component
+    //               meta description (i.e.: proto::binary_expr<Tag, ...>)
+    //    Domain:    the domain this proto transform is defined for
+    //               (for instance: qi::domain)
+    //    DirectorF: the director is the real component form the specified
+    //               domain (i.e.: difference)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_double : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            typedef typename proto::result_of::left<trans>::type left_type;
+            typedef typename proto::result_of::right<trans>::type right_type;
+            typedef typename
+                fusion::result_of::make_list<left_type, right_type>::type
+            list_type;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply1<DirectorF, list_type>::type
+                  , list_type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+            return result::call(
+                fusion::make_list(proto::left(trans), proto::right(trans))
+            );
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating triple-element component meta
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //
+    //    Grammar:   the proto grammar to use as the base for this component
+    //               meta description (i.e.: proto::nary_expr<Tag,a,b,c>)
+    //    Domain:    the domain this proto transform is defined for
+    //               (for instance: qi::domain)
+    //    DirectorF: the director is the real component form the specified
+    //               domain (i.e.: difference)
+    ///////////////////////////////////////////////////////////////////////////
+
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_triple : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            typedef typename proto::result_of::arg_c<trans, 0>::type arg0_type;
+            typedef typename proto::result_of::arg_c<trans, 1>::type arg1_type;
+            typedef typename proto::result_of::arg_c<trans, 2>::type arg2_type;
+
+            typedef typename
+                fusion::result_of::make_list<arg0_type, arg1_type, arg2_type>::type
+            list_type;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply1<DirectorF, list_type>::type
+                  , list_type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+            return result::call(
+                fusion::make_list(proto::arg_c<0>(trans), proto::arg_c<1>(trans), proto::arg_c<2>(trans))
+            );
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating single-element component meta
+    //  descriptions (proto expressions) usable for defining meta grammars
+    //  Only the RHS is stored.
+    //
+    //    Grammar:   the proto grammar to use as the base for this component
+    //               meta description (i.e.: proto::binary_expr<Tag, ...>)
+    //    Domain:    the domain this proto transform is defined for
+    //               (for instance: qi::domain)
+    //    DirectorF: the director is the real component form the specified
+    //               domain (i.e.: difference)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_right : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            typedef typename proto::result_of::right<trans>::type right_type;
+            typedef typename
+                fusion::result_of::make_list<right_type>::type
+            list_type;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply1<DirectorF, list_type>::type
+                  , list_type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+            return result::call(
+                fusion::make_list(proto::right(trans))
+            );
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform that accepts a proto::if_ predicate and
+    //  applies a supplied indirect transform if the predicate is true.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Pred, typename TransformF>
+    struct if_transform
+      : proto::when<proto::if_<Pred>, proto::bind<TransformF> >
+    {
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform that composes components from a fusion::list
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_list : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef
+                traits::make_component<
+                    Domain, Director
+                  , typename Grammar::template
+                        result<void(Expr, State, Visitor)>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(Grammar()(expr, state, visitor));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform that composes a single-element component
+    //  from a 1-arity proto function expression (e.g. f(x))
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_function1 : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 1>::type
+                >::type
+            arg1;
+
+            typedef
+                traits::make_component<
+                    Domain, Director
+                  , typename fusion::result_of::make_cons<arg1>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const&, Visitor&) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(fusion::make_cons(proto::arg(proto::arg_c<1>(expr))));
+        }
+    };
+
+    //  Same as compose_function1, except that DirectorF is a meta-function to
+    //  be evaluated to get the director
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_function1_eval : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 0>::type
+                >::type
+            function;
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 1>::type
+                >::type
+            arg1;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply2<DirectorF, function, arg1>::type
+                  , typename fusion::result_of::make_cons<arg1>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const&, Visitor&) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(
+                fusion::make_cons(proto::arg(proto::arg_c<1>(expr))));
+        }
+    };
+
+    //  Same as compose_function1, except that the generated component holds 
+    //  not only the function argument, but the function tag as well
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_function1_full : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 0>::type
+                >::type
+            function;
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 1>::type
+                >::type
+            arg1;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply2<DirectorF, function, arg1>::type
+                  , typename fusion::result_of::make_list<function, arg1>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& /*state*/, Visitor& /*visitor*/) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(fusion::make_list(
+                    proto::arg(proto::arg_c<0>(expr)),
+                    proto::arg(proto::arg_c<1>(expr))
+                ));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform that composes a 2-element component
+    //  from a 2-arity proto function expression (e.g. f(x, y))
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_function2 : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 1>::type
+                >::type
+            arg1;
+
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 2>::type
+                >::type
+            arg2;
+
+            typedef
+                traits::make_component<
+                    Domain, Director
+                  , typename fusion::result_of::make_list<arg1, arg2>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& /*state*/, Visitor& /*visitor*/) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(fusion::make_list(
+                proto::arg(proto::arg_c<1>(expr))
+              , proto::arg(proto::arg_c<2>(expr))
+            ));
+        }
+    };
+
+    //  Same as compose_function2, except that DirectorF is a meta-function to
+    //  be evaluated to get the director
+    template <typename Grammar, typename Domain, typename DirectorF>
+    struct compose_function2_eval : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 0>::type
+                >::type
+            function;
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 1>::type
+                >::type
+            arg1;
+            typedef typename
+                proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 2>::type
+                >::type
+            arg2;
+
+            typedef
+                traits::make_component<
+                    Domain
+                  , typename mpl::apply2<DirectorF, function, arg1>::type
+                  , typename fusion::result_of::make_list<arg1, arg2>::type
+                  , Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& /*state*/, Visitor& /*visitor*/) const
+        {
+            typedef typename result<void(Expr, State, Visitor)>::make_component result;
+            return result::call(fusion::make_list(
+                proto::arg(proto::arg_c<1>(expr))
+              , proto::arg(proto::arg_c<2>(expr))
+            ));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for directives. The directive (terminal) tag
+    //  is pushed into the modifier state (the Visitor).
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar>
+    struct compose_deep_directive : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            typedef typename
+                add_modifier<
+                    Visitor
+                  , typename proto::result_of::arg<
+                        typename proto::result_of::arg_c<Expr, 0>::type
+                    >::type
+                >::type
+            modifier_type;
+
+            typedef typename
+                Grammar::template result<void(Expr, State, modifier_type)>::type
+            type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor&) const
+        {
+            typename add_modifier<
+                Visitor
+              , typename proto::result_of::arg<
+                    typename proto::result_of::arg_c<Expr, 0>::type
+                >::type
+            >::type
+            modifier;
+            return Grammar()(expr, state, modifier);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating double-element component meta 
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //  This can be used to handle constructs like: 
+    //
+    //    directive[p]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_subscript : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            // apply all grammar transformations mandated for the whole 
+            // expression
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            // this calculates the type of the directive
+            typedef typename proto::result_of::arg_c<trans, 0>::type directive;
+            
+            // this calculates the type of the embedded expression
+            typedef typename proto::result_of::arg_c<trans, 1>::type embedded;
+            
+            // this is the type of the contained data
+            typedef fusion::list<embedded, directive> list_type;
+
+            typedef
+                traits::make_component<Domain, Director, list_type, Visitor>
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+
+            return result::call(
+                list_type(proto::arg_c<1>(trans), proto::arg_c<0>(trans)));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating double-element component meta 
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //  This can be used to handle constructs like: 
+    //
+    //    directive(a)[p]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_subscript_function1 : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            // apply all grammar transformations mandated for the whole 
+            // expression
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            // this calculates the type of the embedded expression
+            typedef typename proto::result_of::arg_c<trans, 1>::type embedded;
+            
+            // this calculates the type of the argument of the function
+            typedef typename
+                proto::result_of::arg_c<
+                    typename proto::result_of::arg_c<trans, 0>::type, 1
+                >::type
+            arg1;
+
+            // this is the type of the contained data
+            typedef fusion::list<embedded, arg1> list_type;
+
+            typedef
+                traits::make_component<
+                    Domain, Director,
+                    list_type,
+                    Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+
+            return result::call(list_type(
+                proto::arg_c<1>(trans), 
+                proto::arg_c<1>(proto::arg_c<0>(trans))));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  A proto transform for creating triple-element component meta 
+    //  descriptions (proto expressions) usable for defining meta grammars.
+    //  This can be used to handle constructs like: 
+    //
+    //    directive(a, b)[p]
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Grammar, typename Domain, typename Director>
+    struct compose_subscript_function2 : Grammar
+    {
+        template<typename Sig>
+        struct result;
+
+        template <typename This, typename Expr, typename State, typename Visitor>
+        struct result<This(Expr, State, Visitor)>
+        {
+            // apply all grammar transformations mandated for the whole 
+            // expression
+            typedef typename
+                Grammar::template result<void(Expr, State, Visitor)>::type
+            trans;
+
+            // this calculates the types of the arguments of the function
+            typedef typename proto::result_of::arg_c<trans, 0>::type arg0;
+            typedef typename proto::result_of::arg_c<arg0, 1>::type arg1;
+            typedef typename proto::result_of::arg_c<arg0, 2>::type arg2;
+
+            // this calculates the type of the embedded expression
+            typedef typename proto::result_of::arg_c<trans, 1>::type embedded;
+            typedef fusion::list<embedded, arg1, arg2> list_type;
+
+            typedef
+                traits::make_component<
+                    Domain, Director,
+                    list_type,
+                    Visitor
+                >
+            make_component;
+
+            typedef typename make_component::type type;
+        };
+
+        template<typename Expr, typename State, typename Visitor>
+        typename result<void(Expr, State, Visitor)>::type
+        operator ()(Expr const& expr, State const& state, Visitor& visitor) const
+        {
+            typedef result<void(Expr, State, Visitor)> apply;
+            typedef typename apply::make_component result;
+            typedef typename apply::list_type list_type;
+            typename apply::trans trans = Grammar()(expr, state, visitor);
+            typename apply::arg0 arg0 = proto::arg_c<0>(trans);
+
+            return result::call(list_type(
+                proto::arg_c<1>(trans), proto::arg_c<1>(arg0), 
+                proto::arg_c<2>(arg0)));
+        }
+    };
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/meta_grammar/grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/meta_grammar/grammar.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,21 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_GRAMMAR_OF_JAN_28_2007_0419PM)
+#define BOOST_SPIRIT_GRAMMAR_OF_JAN_28_2007_0419PM
+
+namespace boost { namespace spirit { namespace meta_grammar
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  Each domain has a proto meta-grammar. This is the metafunction
+    //  that return the domain's meta-grammar.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Domain>
+    struct grammar;
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/modifier.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/modifier.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,90 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_MODIFIER_FEB_05_2007_0259PM)
+#define BOOST_SPIRIT_MODIFIER_FEB_05_2007_0259PM
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //  The modifier is like a set of types. Types can be added (but not 
+    //  removed). The unique feature of the modifier is that addition of
+    //  types is done using inheritance. Thus, checking for membership
+    //  involves checking for inheritance. More importantly, because the
+    //  modifier inherits from a type, the type's members (typedefs,
+    //  nested structs, etc.), are all visible; unless, of course, if the
+    //  member is hidden (newer types take priority) or there's ambiguity.
+    //
+    //      to add:                     add_modifier<Modifier, T>
+    //      to test for membership:     is_member_of_modifier<Modifier, T>
+    //
+    //  The modifier is used as the "Visitor" in proto transforms to
+    //  modify the behavior of the expression template building.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Set = unused_type, typename New = unused_type>
+    struct modifier : Set, New {};
+
+    template <typename Set>
+    struct modifier<Set, unused_type> : Set {};
+
+    template <typename New>
+    struct modifier<unused_type, New> : New {};
+
+    template <>
+    struct modifier<unused_type, unused_type> {};
+        
+    template <typename Modifier, typename New>
+    struct add_modifier
+    {
+        typedef typename // add only if New is not a member
+            mpl::if_<
+                is_base_of<New, Modifier>
+              , Modifier
+              , modifier<Modifier, New>
+            >::type
+        type;
+    };
+    
+    template <typename Modifier, typename T>
+    struct is_member_of_modifier : is_base_of<T, Modifier> {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    //  This is the main customization point for hooking into the 
+    //  make_component mechanism for building /modified/ components.
+    //  The make_component specialization detects modifier Visitors
+    //  and dispatches to the secondary template make_modified_component
+    //  for clients to specialize. By default, the modifier is ignored
+    //  and the control goes back to make_component.
+    //
+    //  (see also: component.hpp)
+    ///////////////////////////////////////////////////////////////////////////
+    namespace traits
+    {
+        template <
+            typename Domain, typename Director, typename Elements
+          , typename Modifier, typename Enable = void>
+        struct make_modified_component : 
+            make_component<Domain, Director, Elements, unused_type>
+        {
+        };
+    
+        template <
+            typename Domain, typename Director
+          , typename Elements, typename Set, typename New>
+        struct make_component<Domain, Director, Elements, modifier<Set, New> >
+          : make_modified_component<Domain, Director, Elements, modifier<Set, New> >
+        {
+        };
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/multi_pass.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/multi_pass.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2001-2008, Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_0201AM)
+#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_0201AM
+
+//  Include everything needed for the default configuration of multi_pass
+#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/std_deque_policy.hpp>
+#include <boost/spirit/home/support/iterators/multi_pass.hpp>
+
+#endif 
Added: trunk/boost/spirit/home/support/nonterminal/detail/expand_arg.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/nonterminal/detail/expand_arg.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,77 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_EXPAND_ARG_FEB_19_2007_1107AM)
+#define BOOST_SPIRIT_EXPAND_ARG_FEB_19_2007_1107AM
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/variant.hpp>
+
+namespace boost { namespace spirit { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Context>
+    struct expand_arg
+    {
+        template <typename T>
+        struct result_type
+        {
+            typedef typename
+                mpl::eval_if<
+                    is_scalar<T>
+                  , mpl::identity<T const &>
+                  , boost::result_of<T(unused_type, Context)>
+                >::type
+            type;
+        };
+        
+        template <typename T>
+        struct result;
+        
+        template <typename F, typename A0>
+        struct result<F(A0)>
+          : result_type<A0> {};
+
+        template <typename F, typename A0>
+        struct result<F(A0&)>
+          : result_type<A0> {};
+
+        expand_arg(Context& context)
+          : context(context)
+        {
+        }
+
+        template <typename T>
+        typename result_type<T>::type
+        call(T const& f, mpl::false_) const
+        {
+            return f(unused, context);
+        }
+
+        template <typename T>
+        typename result_type<T>::type
+        call(T const& val, mpl::true_) const
+        {
+            return val;
+        }
+
+        template <typename T>
+        typename result_type<T>::type
+        operator()(T const& x) const
+        {
+            return call(x, is_scalar<T>());
+        }
+
+        Context& context;
+    };
+    
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,60 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_FILENAME_1 \
+    <boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARG_LIMIT)
+#include BOOST_PP_ITERATE()
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename A)>
+    typename lazy_enable_if_c<
+        (mpl::size<param_types>::value == N)
+      , make_nonterminal_holder<
+            parameterized_nonterminal<
+                Derived
+              , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)>
+            >
+          , Derived
+        >
+    >::type
+    operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
+    {
+        typename
+            make_nonterminal_holder<
+                parameterized_nonterminal<
+                    Derived
+                  , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)>
+                >
+              , Derived
+            >::type
+        result =
+        {{
+            static_cast<Derived const*>(this)
+          , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)>(
+                BOOST_PP_ENUM_PARAMS(N, f))
+        }};
+        return result;
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+
Added: trunk/boost/spirit/home/support/nonterminal/locals.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/nonterminal/locals.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,51 @@
+//  Copyright (c) 2001-2007 Joel de Guzman
+//  Copyright (c) 2001-2008 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_LOCALS_APR_03_2007_0506PM)
+#define BOOST_SPIRIT_LOCALS_APR_03_2007_0506PM
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once      // MS compatible compilers support #pragma once
+#endif
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/bool.hpp>
+
+#if !defined(BOOST_SPIRIT_MAX_LOCALS_SIZE)
+# define BOOST_SPIRIT_MAX_LOCALS_SIZE 10
+#else
+# if BOOST_SPIRIT_MAX_LOCALS_SIZE < 3
+#   undef BOOST_SPIRIT_MAX_LOCALS_SIZE
+#   define BOOST_SPIRIT_MAX_LOCALS_SIZE 10
+# endif
+#endif
+
+namespace boost { namespace spirit 
+{
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+            BOOST_SPIRIT_MAX_LOCALS_SIZE, typename T, mpl::na)
+    >
+    struct locals
+      : mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_MAX_LOCALS_SIZE, T)> {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename T>
+        struct is_locals
+          : mpl::false_ 
+        {};
+
+        template <BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_MAX_LOCALS_SIZE, typename T)>
+        struct is_locals<locals<BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_MAX_LOCALS_SIZE, T)> >
+          : mpl::true_ 
+        {};
+    }
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/nonterminal/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/nonterminal/nonterminal.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,48 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_NONTERMINAL_MAR_06_2007_0236PM)
+#define BOOST_SPIRIT_NONTERMINAL_MAR_06_2007_0236PM
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/joint_view.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+namespace boost { namespace spirit
+{
+    template <typename T, typename Nonterminal>
+    struct nonterminal_holder
+    {
+        typedef Nonterminal nonterminal_type;
+        T held;
+    };
+
+    template <typename T, typename Nonterminal>
+    struct make_nonterminal_holder
+      : proto::terminal<nonterminal_holder<T, Nonterminal> >
+    {
+    };
+
+    template <typename Nonterminal, typename FSequence>
+    struct parameterized_nonterminal
+    {
+        Nonterminal const* ptr;
+        FSequence fseq;
+    };
+
+    template <typename Nonterminal>
+    struct nonterminal_object
+    {
+        Nonterminal obj;
+    };
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/placeholders.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/placeholders.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,400 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+    Copyright (c) 2001-2008 Hartmut Kaiser
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_PLACEHOLDERS_NOV_18_2006_0326PM)
+#define BOOST_SPIRIT_PLACEHOLDERS_NOV_18_2006_0326PM
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/mpl/bool.hpp>
+
+namespace boost { namespace spirit
+{
+    //  This file contains the common placeholders. If you have a placeholder
+    //  that can be (re)used in different spirit domains. This is the place
+    //  to put them in.
+
+    namespace tag
+    {
+        struct char_ {};
+        struct wchar {};
+        struct lit {};
+        struct wlit {};
+
+        struct bin {};
+        struct oct {};
+        struct hex {};
+        
+        struct byte {};
+        struct word {};
+        struct dword {};
+        struct big_word {};
+        struct big_dword {};
+        struct little_word {};
+        struct little_dword {};
+#ifdef BOOST_HAS_LONG_LONG
+        struct qword {};
+        struct big_qword {};
+        struct little_qword {};
+#endif
+
+        struct ushort {};
+        struct ulong {};
+        struct uint {};
+        struct short_ {};
+        struct long_ {};
+        struct int_ {};
+#ifdef BOOST_HAS_LONG_LONG
+        struct ulong_long {};
+        struct long_long {};
+#endif
+        struct float_ {};
+        struct double_ {};
+        struct long_double {};
+
+        struct left_align {};
+        struct right_align {};
+        struct center {};
+
+        struct delimit {};
+        struct verbatim {};
+
+        struct none {};
+        struct eps {};
+        struct lexeme {};
+        struct lazy {};
+        struct omit {};
+        struct raw {};
+        
+        struct stream {};
+        struct wstream {};
+        
+        struct token {};
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    typedef proto::terminal<tag::char_>::type char_type;
+    typedef proto::terminal<tag::wchar>::type wchar_type;
+    typedef proto::terminal<tag::lit>::type lit_type;
+    typedef proto::terminal<tag::wlit>::type wlit_type;
+    
+    typedef proto::terminal<tag::bin>::type bin_type;
+    typedef proto::terminal<tag::oct>::type oct_type;
+    typedef proto::terminal<tag::hex>::type hex_type;
+
+    typedef proto::terminal<tag::byte>::type byte_type;
+    typedef proto::terminal<tag::word>::type word_type;
+    typedef proto::terminal<tag::dword>::type dword_type;
+    typedef proto::terminal<tag::big_word>::type big_word_type;
+    typedef proto::terminal<tag::big_dword>::type big_dword_type;
+    typedef proto::terminal<tag::little_word>::type little_word_type;
+    typedef proto::terminal<tag::little_dword>::type little_dword_type;
+#ifdef BOOST_HAS_LONG_LONG
+    typedef proto::terminal<tag::qword>::type qword_type;
+    typedef proto::terminal<tag::big_qword>::type big_qword_type;
+    typedef proto::terminal<tag::little_qword>::type little_qword_type;
+#endif
+
+    typedef proto::terminal<tag::ushort>::type ushort_type;
+    typedef proto::terminal<tag::ulong>::type ulong_type;
+    typedef proto::terminal<tag::uint>::type uint_type;
+    typedef proto::terminal<tag::short_>::type short_type;
+    typedef proto::terminal<tag::long_>::type long_type;
+    typedef proto::terminal<tag::int_>::type int_type;
+#ifdef BOOST_HAS_LONG_LONG
+    typedef proto::terminal<tag::ulong_long>::type ulong_long_type;
+    typedef proto::terminal<tag::long_long>::type long_long_type;
+#endif
+    typedef proto::terminal<tag::float_>::type float_type;
+    typedef proto::terminal<tag::double_>::type double_type;
+    typedef proto::terminal<tag::long_double>::type long_double_type;
+
+    typedef proto::terminal<tag::left_align>::type left_align_type;
+    typedef proto::terminal<tag::right_align>::type right_align_type;
+    typedef proto::terminal<tag::center>::type center_type;
+
+    typedef proto::terminal<tag::delimit>::type delimit_type;
+    typedef proto::terminal<tag::verbatim>::type verbatim_type;
+
+    typedef proto::terminal<tag::none>::type none_type;
+    typedef proto::terminal<tag::eps>::type eps_type;
+    typedef proto::terminal<tag::lexeme>::type lexeme_type;
+    typedef proto::terminal<tag::lazy>::type lazy_type;
+    typedef proto::terminal<tag::omit>::type omitted;
+    typedef proto::terminal<tag::raw>::type raw_type;
+
+    typedef proto::terminal<tag::stream>::type stream_type;
+    typedef proto::terminal<tag::wstream>::type wstream_type;
+
+    typedef proto::terminal<tag::token>::type token_type;
+
+    ////////////////////////////////////////////////////////////////////////////
+    proto::terminal<tag::char_>::type const char_ = {{}};
+    proto::terminal<tag::wchar>::type const wchar = {{}};
+    proto::terminal<tag::lit>::type const lit = {{}};
+    proto::terminal<tag::wlit>::type const wlit = {{}};
+    
+    proto::terminal<tag::bin>::type const bin = {{}};
+    proto::terminal<tag::oct>::type const oct = {{}};
+    proto::terminal<tag::hex>::type const hex = {{}};
+
+    proto::terminal<tag::byte>::type const byte = {{}};
+    proto::terminal<tag::word>::type const word = {{}};
+    proto::terminal<tag::dword>::type const dword = {{}};
+    proto::terminal<tag::big_word>::type const big_word = {{}};
+    proto::terminal<tag::big_dword>::type const big_dword = {{}};
+    proto::terminal<tag::little_word>::type const little_word = {{}};
+    proto::terminal<tag::little_dword>::type const little_dword = {{}};
+#ifdef BOOST_HAS_LONG_LONG
+    proto::terminal<tag::qword>::type const qword = {{}};
+    proto::terminal<tag::big_qword>::type const big_qword = {{}};
+    proto::terminal<tag::little_qword>::type const little_qword = {{}};
+#endif
+
+    proto::terminal<tag::ushort>::type const ushort = {{}};
+    proto::terminal<tag::ulong>::type const ulong = {{}};
+    proto::terminal<tag::uint>::type const uint = {{}};
+    proto::terminal<tag::short_>::type const short_ = {{}};
+    proto::terminal<tag::long_>::type const long_ = {{}};
+    proto::terminal<tag::int_>::type const int_ = {{}};
+#ifdef BOOST_HAS_LONG_LONG
+    proto::terminal<tag::ulong_long>::type const ulong_long = {{}};
+    proto::terminal<tag::long_long>::type const long_long = {{}};
+#endif
+    proto::terminal<tag::float_>::type const float_ = {{}};
+    proto::terminal<tag::double_>::type const double_ = {{}};
+    proto::terminal<tag::long_double>::type const long_double = {{}};
+
+    proto::terminal<tag::left_align>::type const left_align = {{}};
+    proto::terminal<tag::right_align>::type const right_align = {{}};
+    proto::terminal<tag::center>::type const center = {{}};
+
+    proto::terminal<tag::delimit>::type const delimit = {{}};
+    proto::terminal<tag::verbatim>::type const verbatim = {{}};
+
+    proto::terminal<tag::none>::type const none = {{}};
+    proto::terminal<tag::eps>::type const eps = {{}};
+    proto::terminal<tag::lexeme>::type const lexeme = {{}};
+    proto::terminal<tag::lazy>::type const lazy = {{}};
+    proto::terminal<tag::omit>::type const omit = {{}};
+    proto::terminal<tag::raw>::type const raw = {{}};
+
+    proto::terminal<tag::stream>::type const stream = {{}};
+    proto::terminal<tag::wstream>::type const wstream = {{}};
+
+    proto::terminal<tag::token>::type const token = {{}};
+
+//  Some platforms/compilers have conflict with these terminals below
+//  we'll provide variations for them with trailing underscores as
+//  substitutes.
+
+    proto::terminal<tag::uint>::type const uint_ = {{}};
+
+#if defined(__GNUC__)
+    inline void silence_unused_warnings__placeholders()
+    {
+        (void) char_; (void) wchar; (void) lit; (void) wlit;
+        (void) bin; (void) oct; (void) hex;
+        (void) byte; (void) word; (void) dword; 
+        (void) big_word; (void) big_dword; 
+        (void) little_word; (void) little_dword; 
+        (void) ushort; (void) uint; (void) ulong;
+        (void) short_; (void) int_; (void) long_;
+#ifdef BOOST_HAS_LONG_LONG
+        (void) qword; (void) little_qword; (void) big_qword;
+        (void) ulong_long; (void) long_long;
+#endif
+        (void) float_; (void) double_; (void) long_double;
+        (void) left_align; (void) right_align; (void) center;
+        (void) delimit; (void) verbatim;
+        (void) none; (void) eps; (void) lazy; (void) lexeme; 
+        (void) omit; (void) raw;
+        (void) stream; (void) wstream;
+        
+        (void) token;
+    }
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is an int tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_int_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::bin, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::oct, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::hex, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::ushort, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::ulong, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::uint, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::short_, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::long_, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::int_, Domain> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <typename Domain>
+    struct is_int_tag<tag::ulong_long, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_tag<tag::long_long, Domain> : mpl::true_ {};
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is an integer type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_int_lit_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_int_lit_tag<short, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_int_lit_tag<unsigned short, Domain> : mpl::true_ {};
+        
+    template <typename Domain>
+    struct is_int_lit_tag<int, Domain> : mpl::true_ {};
+        
+    template <typename Domain>
+    struct is_int_lit_tag<unsigned int, Domain> : mpl::true_ {};
+        
+    template <typename Domain>
+    struct is_int_lit_tag<long, Domain> : mpl::true_ {};
+        
+    template <typename Domain>
+    struct is_int_lit_tag<unsigned long, Domain> : mpl::true_ {};
+    
+#ifdef BOOST_HAS_LONG_LONG
+    template <typename Domain>
+    struct is_int_lit_tag<boost::ulong_long_type, Domain> : mpl::true_ {};
+        
+    template <typename Domain>
+    struct is_int_lit_tag<boost::long_long_type, Domain> : mpl::true_ {};
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is an floating point tag
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_real_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_real_tag<tag::float_, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_real_tag<tag::double_, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_real_tag<tag::long_double, Domain> : mpl::true_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a floating type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_real_lit_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_real_lit_tag<float, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_real_lit_tag<double, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_real_lit_tag<long double, Domain> : mpl::true_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a character literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_char_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_char_tag<tag::char_, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_char_tag<tag::wchar, Domain> : mpl::true_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a character literal type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_lit_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_lit_tag<tag::lit, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_lit_tag<tag::wlit, Domain> : mpl::true_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a binary type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_binary_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::byte, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::word, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::dword, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::big_word, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::big_dword, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::little_word, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::little_dword, Domain> : mpl::true_ {};
+
+#ifdef BOOST_HAS_LONG_LONG
+    template <typename Domain>
+    struct is_binary_tag<tag::qword, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::big_qword, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_binary_tag<tag::little_qword, Domain> : mpl::true_ {};
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////
+    // test if a tag is a stream terminal 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain>
+    struct is_stream_tag : mpl::false_ {};
+
+    template <typename Domain>
+    struct is_stream_tag<tag::stream, Domain> : mpl::true_ {};
+
+    template <typename Domain>
+    struct is_stream_tag<tag::wstream, Domain> : mpl::true_ {};
+
+}}
+
+#endif
Added: trunk/boost/spirit/home/support/safe_bool.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/safe_bool.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,57 @@
+/*=============================================================================
+    Copyright (c) 2003 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_SAFE_BOOL_HPP)
+#define BOOST_SPIRIT_SAFE_BOOL_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost { namespace spirit
+{
+    namespace detail
+    {
+        template <typename T>
+        struct no_base {};
+
+        template <typename T>
+        struct safe_bool_impl
+        {
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+            void stub(T*) {}
+            typedef void (safe_bool_impl::*type)(T*);
+#else
+            typedef T* TP; // workaround to make parsing easier
+            TP stub;
+            typedef TP safe_bool_impl::*type;
+#endif
+        };
+    }
+
+    template <typename Derived, typename Base = detail::no_base<Derived> >
+    struct safe_bool : Base
+    {
+    private:
+        typedef detail::safe_bool_impl<Derived> impl_type;
+        typedef typename impl_type::type bool_type;
+
+    public:
+        operator bool_type() const
+        {
+            return static_cast<const Derived*>(this)->operator_bool() ?
+                &impl_type::stub : 0;
+        }
+
+        operator bool_type()
+        {
+            return static_cast<Derived*>(this)->operator_bool() ?
+                &impl_type::stub : 0;
+        }
+    };
+}}
+
+#endif
+
Added: trunk/boost/spirit/home/support/standard.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/standard.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_STANDARD_JAN_31_2006_0529PM)
+#define SPIRIT_STANDARD_JAN_31_2006_0529PM
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit { namespace standard
+{
+    typedef spirit::char_class::standard char_set;
+    namespace tag = spirit::char_class::tag;
+
+    template <typename Class>
+    struct make_tag 
+      : proto::terminal<spirit::char_class::key<char_set, Class> > {};
+
+    typedef make_tag<tag::alnum>::type alnum_type;
+    typedef make_tag<tag::alpha>::type alpha_type;
+    typedef make_tag<tag::blank>::type blank_type;
+    typedef make_tag<tag::cntrl>::type cntrl_type;
+    typedef make_tag<tag::digit>::type digit_type;
+    typedef make_tag<tag::graph>::type graph_type;
+    typedef make_tag<tag::print>::type print_type;
+    typedef make_tag<tag::punct>::type punct_type;
+    typedef make_tag<tag::space>::type space_type;
+    typedef make_tag<tag::xdigit>::type xdigit_type;
+
+    alnum_type const alnum = {{}};
+    alpha_type const alpha = {{}};
+    blank_type const blank = {{}};
+    cntrl_type const cntrl = {{}};
+    digit_type const digit = {{}};
+    graph_type const graph = {{}};
+    print_type const print = {{}};
+    punct_type const punct = {{}};
+    space_type const space = {{}};
+    xdigit_type const xdigit = {{}};
+
+    typedef proto::terminal<
+        spirit::char_class::no_case_tag<char_set> >::type 
+    no_case_type;
+
+    no_case_type const no_case = no_case_type();
+
+    typedef proto::terminal<
+        spirit::char_class::lower_case_tag<char_set> >::type 
+    lower_type;
+    typedef proto::terminal<
+        spirit::char_class::upper_case_tag<char_set> >::type 
+    upper_type;
+
+    lower_type const lower = lower_type();
+    upper_type const upper = upper_type();
+
+#if defined(__GNUC__)
+    inline void silence_unused_warnings__standard()
+    {
+        (void) alnum; (void) alpha; (void) blank; (void) cntrl; (void) digit; 
+        (void) graph; (void) print; (void) punct; (void) space;  (void) xdigit;
+    }
+#endif
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/standard_wide.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/standard_wide.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,70 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying 
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(SPIRIT_STANDARD_WIDE_JAN_31_2006_0529PM)
+#define SPIRIT_STANDARD_WIDE_JAN_31_2006_0529PM
+
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+
+namespace boost { namespace spirit { namespace standard_wide
+{
+    typedef spirit::char_class::standard_wide char_set;
+    namespace tag = spirit::char_class::tag;
+
+    template <typename Class>
+    struct make_tag 
+      : proto::terminal<spirit::char_class::key<char_set, Class> > {};
+
+    typedef make_tag<tag::alnum>::type alnum_type;
+    typedef make_tag<tag::alpha>::type alpha_type;
+    typedef make_tag<tag::blank>::type blank_type;
+    typedef make_tag<tag::cntrl>::type cntrl_type;
+    typedef make_tag<tag::digit>::type digit_type;
+    typedef make_tag<tag::graph>::type graph_type;
+    typedef make_tag<tag::print>::type print_type;
+    typedef make_tag<tag::punct>::type punct_type;
+    typedef make_tag<tag::space>::type space_type;
+    typedef make_tag<tag::xdigit>::type xdigit_type;
+
+    alnum_type const alnum = {{}};
+    alpha_type const alpha = {{}};
+    blank_type const blank = {{}};
+    cntrl_type const cntrl = {{}};
+    digit_type const digit = {{}};
+    graph_type const graph = {{}};
+    print_type const print = {{}};
+    punct_type const punct = {{}};
+    space_type const space = {{}};
+    xdigit_type const xdigit = {{}};
+
+    typedef proto::terminal<
+        spirit::char_class::no_case_tag<char_set> >::type 
+    no_case_type;
+
+    no_case_type const no_case = no_case_type();
+
+    typedef proto::terminal<
+        spirit::char_class::lower_case_tag<char_set> >::type 
+    lower_type;
+    typedef proto::terminal<
+        spirit::char_class::upper_case_tag<char_set> >::type 
+    upper_type;
+
+    lower_type const lower = lower_type();
+    upper_type const upper = upper_type();
+
+#if defined(__GNUC__)
+    inline void silence_unused_warnings__standard_wide()
+    {
+        (void) alnum; (void) alpha; (void) blank; (void) cntrl; (void) digit; 
+        (void) graph; (void) print; (void) punct; (void) space;  (void) xdigit;
+    }
+#endif
+
+}}}
+
+#endif
Added: trunk/boost/spirit/home/support/unused.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/unused.hpp	2008-04-12 20:54:10 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,52 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    Distributed under the Boost Software License, Version 1.0. (See accompanying
+    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_UNUSED_APR_16_2006_0616PM)
+#define BOOST_SPIRIT_UNUSED_APR_16_2006_0616PM
+
+#include <boost/fusion/include/unused.hpp>
+#include <boost/fusion/include/empty.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // since boost::fusion now supports exactly what we need, unused is simply
+    // imported from the fusion namespace
+    ///////////////////////////////////////////////////////////////////////////
+    typedef boost::fusion::unused_type unused_type;
+    using boost::fusion::unused;
+
+    ///////////////////////////////////////////////////////////////////////////
+    namespace traits
+    {
+        // We use this test to detect if the argument is not a unused_type
+        template <typename T>
+        struct is_not_unused
+          : mpl::not_<is_same<T, unused_type> >
+        {};
+
+        // Return unused_type if Target is same as Actual, else
+        // return Attribute (Attribute defaults to Actual).
+        template <typename Target, typename Actual, typename Attribute = Actual>
+        struct unused_if_same
+          : mpl::if_<is_same<Target, Actual>, unused_type, Attribute>
+        {};
+
+        // Return unused_type if Sequence is empty, else return Attribute.
+        //  (Attribute defaults to Sequence).
+        template <typename Sequence, typename Attribute = Sequence>
+        struct unused_if_empty
+          : mpl::if_<fusion::result_of::empty<Sequence>, unused_type, Attribute>
+        {};
+    }
+
+}}
+
+#endif