|
Boost-Commit : |
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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk