diff --git a/example/invert.cpp b/example/invert.cpp index 830f7cc..e9f547d 100644 --- a/example/invert.cpp +++ b/example/invert.cpp @@ -32,7 +32,7 @@ using phoenix::evaluator; template <> struct invert_actions::when : proto::call< - phoenix::expression::make_minus( + phoenix::functional::make_minus( evaluator(proto::_left, phoenix::_context) , evaluator(proto::_right, phoenix::_context) ) @@ -42,7 +42,7 @@ struct invert_actions::when template <> struct invert_actions::when : proto::call< - phoenix::expression::make_plus( + phoenix::functional::make_plus( evaluator(proto::_left, phoenix::_context) , evaluator(proto::_right, phoenix::_context) ) @@ -52,7 +52,7 @@ struct invert_actions::when template <> struct invert_actions::when : proto::call< - phoenix::expression::make_divides( + phoenix::functional::make_divides( evaluator(proto::_left, phoenix::_context) , evaluator(proto::_right, phoenix::_context) ) @@ -62,7 +62,7 @@ struct invert_actions::when template <> struct invert_actions::when : proto::call< - phoenix::expression::make_multiplies( + phoenix::functional::make_multiplies( evaluator(proto::_left, phoenix::_context) , evaluator(proto::_right, phoenix::_context) ) @@ -95,15 +95,18 @@ template typename boost::phoenix::result_of::eval< Expr const& - , phoenix::result_of::context::type + , phoenix::result_of::make_context< + phoenix::result_of::make_env<>::type + , invert_actions + >::type >::type invert(Expr const & expr) { return phoenix::eval( expr - , phoenix::context( - phoenix::nothing + , phoenix::make_context( + phoenix::make_env() , invert_actions() ) ); @@ -128,4 +131,3 @@ int main() print_expr(_1 * invert(_2 - _3)); } - diff --git a/example/parallel_for.cpp b/example/parallel_for.cpp index 1926434..e021df0 100644 --- a/example/parallel_for.cpp +++ b/example/parallel_for.cpp @@ -53,13 +53,10 @@ struct omp_for_gen : init(init), cond(cond), step(step) {} template - typename - boost::result_of< - expression::make_omp_for(Init, Cond, Step, Do) - >::type const + typename result_of::make_omp_for::type const operator[](Do const& do_) const { - return expression::make_omp_for()(init, cond, step, do_); + return make_omp_for(init, cond, step, do_); } Init init; @@ -95,19 +92,29 @@ struct parallel_actions::when // Doing the same as actor::operator template -typename boost::result_of< - boost::phoenix::evaluator( - Expr const & - , typename boost::phoenix::result_of::context< - boost::phoenix::vector4 - , parallel_actions +typename boost::phoenix::result_of::eval< + Expr const & + , typename boost::phoenix::result_of::make_context< + typename boost::phoenix::result_of::make_env< + Expr const * + , A0 & + , A1 & + , A2 & >::type - ) + , parallel_actions + >::type >::type -parallel_eval(Expr const & expr, A0 & a0, A1 & a1, A2 & a2) +parallel_eval(Expr & expr, A0 & a0, A1 & a1, A2 & a2) { - boost::phoenix::vector4 env = {boost::addressof(expr), a0, a1, a2}; - return boost::phoenix::eval(expr, boost::phoenix::context(env, parallel_actions())); + Expr const * this_ = boost::addressof(expr); + return + boost::phoenix::eval( + expr + , boost::phoenix::make_context( + boost::phoenix::make_env(this_, a0, a1, a2) + , parallel_actions() + ) + ); } // changing evaluation mechanism on the fly @@ -123,21 +130,21 @@ namespace boost { namespace phoenix : proto::call< evaluator( proto::_child0 - , functional::context( + , functional::make_context( _env , parallel_actions() ) - , int() + , unused()//mpl::void_() ) > {}; }} template -typename expression::parallel::type const +typename result_of::make_parallel::type parallel(Expr const & expr) { - return expression::parallel::make(expr); + return make_parallel(expr); } //////////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/phoenix/bind/detail/member_variable.hpp b/include/boost/phoenix/bind/detail/member_variable.hpp index cb35704..a2a0f4b 100644 --- a/include/boost/phoenix/bind/detail/member_variable.hpp +++ b/include/boost/phoenix/bind/detail/member_variable.hpp @@ -8,6 +8,7 @@ #define BOOST_PHOENIX_CORE_DETAIL_MEMBER_VARIABLE_HPP #include +#include namespace boost { namespace phoenix { namespace detail { diff --git a/include/boost/phoenix/core/detail/expression.hpp b/include/boost/phoenix/core/detail/expression.hpp index 5d0a3dc..7b239b1 100644 --- a/include/boost/phoenix/core/detail/expression.hpp +++ b/include/boost/phoenix/core/detail/expression.hpp @@ -28,6 +28,8 @@ , SEQ \ , BOOST_PHOENIX_DEFINE_EXPRESSION_EXPRESSION_DEFAULT \ , BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_DEFAULT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_DEFAULT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_DEFAULT \ , _ \ ) \ /**/ @@ -38,6 +40,8 @@ , GRAMMAR_SEQ \ , BOOST_PHOENIX_DEFINE_EXPRESSION_EXPRESSION_VARARG \ , BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_VARARG \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_VARARG \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_VARARG \ , LIMIT \ ) \ /**/ @@ -47,7 +51,9 @@ NAME_SEQ \ , GRAMMAR_SEQ \ , BOOST_PHOENIX_DEFINE_EXPRESSION_EXPRESSION_EXT \ - , BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_VARARG \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_DEFAULT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_DEFAULT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_DEFAULT \ , ACTOR \ ) \ /**/ @@ -58,6 +64,8 @@ , GRAMMAR_SEQ \ , BOOST_PHOENIX_DEFINE_EXPRESSION_EXPRESSION_VARARG_EXT \ , BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_VARARG \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_VARARG \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_VARARG \ , ACTOR \ ) \ /**/ @@ -74,7 +82,7 @@ namespace E { E :: \ /**/ -#define BOOST_PHOENIX_DEFINE_EXPRESSION_BASE(NAME_SEQ, GRAMMAR_SEQ, EXPRESSION, RULE, DATA) \ +#define BOOST_PHOENIX_DEFINE_EXPRESSION_BASE(NAME_SEQ, GRAMMAR_SEQ, EXPRESSION, RULE, RESULT_OF_MAKE, MAKE_EXPRESSION, DATA) \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PHOENIX_DEFINE_EXPRESSION_NAMESPACE \ , _ \ @@ -97,6 +105,13 @@ BOOST_PP_SEQ_FOR_EACH( namespace expression \ { \ EXPRESSION(NAME_SEQ, GRAMMAR_SEQ, DATA) \ + } \ + namespace rule \ + { \ + RULE(NAME_SEQ, GRAMMAR_SEQ, DATA) \ + } \ + namespace functional \ + { \ typedef \ boost::proto::functional::make_expr< \ tag:: BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ @@ -106,10 +121,12 @@ BOOST_PP_SEQ_FOR_EACH( , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ ); \ } \ - namespace rule \ + namespace result_of \ { \ - RULE(NAME_SEQ, GRAMMAR_SEQ, DATA) \ + RESULT_OF_MAKE(NAME_SEQ, GRAMMAR_SEQ, DATA) \ } \ + MAKE_EXPRESSION(NAME_SEQ, GRAMMAR_SEQ, DATA) \ + \ BOOST_PP_SEQ_FOR_EACH( \ BOOST_PHOENIX_DEFINE_EXPRESSION_NAMESPACE_END \ , _ \ @@ -152,10 +169,49 @@ namespace boost { namespace phoenix /**/ #define BOOST_PHOENIX_DEFINE_EXPRESSION_RULE_DEFAULT(NAME_SEQ, GRAMMAR_SEQ, D) \ -struct BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ - : expression:: BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ - \ - {}; \ + struct BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + : expression:: BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + \ + {}; \ +/**/ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_DEFAULT(NAME_SEQ, GRAMMAR_SEQ, D) \ + template \ + struct BOOST_PP_CAT(make_, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ))) \ + : boost::result_of< \ + functional:: \ + BOOST_PP_CAT( \ + make_ \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + )(BOOST_PHOENIX_A(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ))) \ + > \ + {}; \ +/**/ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_DEFAULT(NAME_SEQ, GRAMMAR_SEQ, D) \ + template \ + typename \ + result_of::BOOST_PP_CAT( \ + make_ \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + )< \ + BOOST_PHOENIX_A(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ)) \ + >::type const \ + inline BOOST_PP_CAT( \ + make_ \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + )( \ + BOOST_PHOENIX_A_const_ref_a(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ)) \ + ) \ + { \ + return \ + functional::BOOST_PP_CAT( \ + make_ \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + )()( \ + BOOST_PHOENIX_a(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ)) \ + ); \ + } \ /**/ #define BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG_R(_, N, NAME) \ @@ -216,7 +272,7 @@ struct BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) ) \ )() \ BOOST_PP_COMMA_IF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ))) \ - proto::vararg< \ + boost::proto::vararg< \ BOOST_PP_SEQ_ELEM( \ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(GRAMMAR_SEQ)) \ , GRAMMAR_SEQ \ @@ -225,6 +281,51 @@ struct BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) > \ {}; \ /**/ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_VARARG_R(Z, N, NAME) \ + template \ + struct BOOST_PP_CAT(make_, NAME) \ + : boost::result_of< \ + functional:: BOOST_PP_CAT(make_, NAME)( \ + BOOST_PHOENIX_A(N) \ + ) \ + > \ + {}; \ +/**/ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_VARARG(NAME_SEQ, GRAMMAR_SEQ, LIMIT) \ + template \ + struct BOOST_PP_CAT( \ + make_ \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + ); \ + BOOST_PP_REPEAT_FROM_TO( \ + 1 \ + , LIMIT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_RESULT_OF_MAKE_VARARG_R \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + ) \ +/**/ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_VARARG_R(Z, N, NAME) \ + template \ + typename \ + result_of:: BOOST_PP_CAT(make_, NAME)< \ + BOOST_PHOENIX_A(N) \ + >::type \ + inline BOOST_PP_CAT(make_, NAME)(BOOST_PHOENIX_A_const_ref_a(N)) \ + { \ + return functional::BOOST_PP_CAT(make_, NAME)()(BOOST_PHOENIX_a(N)); \ + } \ + +#define BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_VARARG(NAME_SEQ, GRAMMAR_SEQ, LIMIT) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1 \ + , LIMIT \ + , BOOST_PHOENIX_DEFINE_EXPRESSION_MAKE_EXPRESSION_VARARG_R \ + , BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(NAME_SEQ)) \ + ) \ +/**/ #define BOOST_PHOENIX_DEFINE_EXPRESSION_EXPRESSION_EXT(NAME_SEQ, GRAMMAR_SEQ, ACTOR) \ template \ diff --git a/include/boost/phoenix/core/environment.hpp b/include/boost/phoenix/core/environment.hpp index bfc1622..20e9f1d 100644 --- a/include/boost/phoenix/core/environment.hpp +++ b/include/boost/phoenix/core/environment.hpp @@ -20,6 +20,8 @@ namespace boost { namespace phoenix { + struct unused {}; + namespace result_of { template @@ -27,6 +29,11 @@ namespace boost { namespace phoenix { typedef vector2 type; }; + + template + struct make_context + : context + {}; template struct env @@ -113,6 +120,10 @@ namespace boost { namespace phoenix } }; + struct make_context + : context + {}; + struct env { BOOST_PROTO_CALLABLE() @@ -208,6 +219,13 @@ namespace boost { namespace phoenix return e; } + template + typename result_of::context::type const + inline make_context(Env const& env, Actions const& actions) + { + return context(env, actions); + } + template typename result_of::context::type const inline context(Env & env, Actions const& actions) @@ -215,6 +233,13 @@ namespace boost { namespace phoenix vector2 e = {env, actions}; return e; } + + template + typename result_of::context::type const + inline make_context(Env & env, Actions const& actions) + { + return context(env, actions); + } template typename result_of::context::type const @@ -224,6 +249,13 @@ namespace boost { namespace phoenix return e; } + template + typename result_of::context::type const + inline make_context(Env const& env, Actions & actions) + { + return context(env, actions); + } + template typename result_of::context::type const inline context(Env & env, Actions & actions) @@ -231,6 +263,13 @@ namespace boost { namespace phoenix vector2 e = {env, actions}; return e; } + + template + typename result_of::context::type const + inline make_context(Env & env, Actions & actions) + { + return context(env, actions); + } struct _env : proto::transform<_env> @@ -273,6 +312,11 @@ namespace boost { namespace phoenix } }; + template + struct _env::impl + : _env::impl + {}; + template typename fusion::result_of::at_c::type inline env(Context & ctx) @@ -328,6 +372,11 @@ namespace boost { namespace phoenix } }; + template + struct _actions::impl + : _actions::impl + {}; + template typename fusion::result_of::at_c::type inline actions(Context & ctx) @@ -342,6 +391,61 @@ namespace boost { namespace phoenix return fusion::at_c<1>(ctx); } + namespace result_of + { + template < + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( + BOOST_PHOENIX_LIMIT + , typename A + , mpl::void_ + ) + , typename Dummy = void + > + struct make_env; + + #define BOOST_PHOENIX_M0(Z, N, D) \ + template \ + struct make_env \ + { \ + typedef BOOST_PP_CAT(vector, N) type; \ + }; \ + /**/ + BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, BOOST_PHOENIX_M0, _) + #undef BOOST_PHOENIX_M0 + } + + result_of::make_env<>::type + inline make_env() + { + return result_of::make_env<>::type(); + } +#define BOOST_PHOENIX_M0(Z, N, D) \ + template \ + typename result_of::make_env::type \ + inline make_env(BOOST_PHOENIX_A_ref_a(N)) \ + { \ + typename result_of::make_env::type \ + env = \ + { \ + BOOST_PHOENIX_a(N) \ + }; \ + return env; \ + }; \ + template \ + typename result_of::make_env::type \ + inline make_env(BOOST_PHOENIX_A_const_ref_a(N)) \ + { \ + typename result_of::make_env::type \ + env = \ + { \ + BOOST_PHOENIX_a(N) \ + }; \ + return env; \ + }; \ + /**/ + BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, BOOST_PHOENIX_M0, _) + #undef BOOST_PHOENIX_M0 + template struct is_environment : fusion::traits::is_sequence {}; }} diff --git a/include/boost/phoenix/core/meta_grammar.hpp b/include/boost/phoenix/core/meta_grammar.hpp index 4dbe8e6..f79f305 100644 --- a/include/boost/phoenix/core/meta_grammar.hpp +++ b/include/boost/phoenix/core/meta_grammar.hpp @@ -74,8 +74,32 @@ namespace boost { namespace phoenix return what()(e, env(s), actions(s)); } }; + + template + struct impl + : proto::transform_impl + { + typedef + meta_grammar::impl< + Expr + , typename result_of::env::type + , typename result_of::actions::type + > + what; + + typedef typename what::result_type result_type; + + result_type operator()( + typename impl::expr_param e + , typename impl::state_param s + , typename impl::data_param + ) const + { + return what()(e, env(s), actions(s)); + } + }; }; - + ///////////////////////////////////////////////////////////////////////////// // Set of default actions. Extend this whenever you add a new phoenix // construct diff --git a/include/boost/phoenix/operator/detail/define_operator.hpp b/include/boost/phoenix/operator/detail/define_operator.hpp index f8d7730..cc35f1a 100644 --- a/include/boost/phoenix/operator/detail/define_operator.hpp +++ b/include/boost/phoenix/operator/detail/define_operator.hpp @@ -25,12 +25,37 @@ {}; \ /**/ +#define BOOST_PHOENIX_UNARY_FUNCTIONAL(__, ___, name) \ + namespace functional \ + { \ + typedef \ + proto::functional::make_expr \ + BOOST_PP_CAT(make_, name); \ + } \ + namespace result_of \ + { \ + template \ + struct BOOST_PP_CAT(make_, name) \ + : boost::result_of< \ + functional:: BOOST_PP_CAT(make_, name)( \ + Operand \ + ) \ + > \ + {}; \ + } \ + template \ + typename result_of::BOOST_PP_CAT(make_, name)::type \ + inline BOOST_PP_CAT(make_, name)(Operand const & operand) \ + { \ + return functional::BOOST_PP_CAT(make_, name)()(operand); \ + } \ +/**/ + #define BOOST_PHOENIX_BINARY_EXPRESSION(__, ___, name) \ template \ struct name \ : expr \ {}; \ - typedef proto::functional::make_expr BOOST_PP_CAT(make_, name); \ /**/ #define BOOST_PHOENIX_BINARY_RULE(__, ___, name) \ @@ -39,6 +64,32 @@ {}; \ /**/ +#define BOOST_PHOENIX_BINARY_FUNCTIONAL(__, ___, name) \ + namespace functional \ + { \ + typedef \ + proto::functional::make_expr \ + BOOST_PP_CAT(make_, name); \ + } \ + namespace result_of \ + { \ + template \ + struct BOOST_PP_CAT(make_, name) \ + : boost::result_of< \ + functional:: BOOST_PP_CAT(make_, name)( \ + Lhs, Rhs \ + ) \ + > \ + {}; \ + } \ + template \ + typename result_of::BOOST_PP_CAT(make_, name)::type \ + inline BOOST_PP_CAT(make_, name)(Lhs const & lhs, Rhs const & rhs) \ + { \ + return functional::BOOST_PP_CAT(make_, name)()(lhs, rhs); \ + } \ +/**/ + #define BOOST_PHOENIX_GRAMMAR(_, __, name) \ template \ struct meta_grammar::case_ \ @@ -54,8 +105,10 @@ BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_UNARY_RULE, _, ops) \ } \ BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_GRAMMAR, _, ops) \ + BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_UNARY_FUNCTIONAL, _, ops) \ /**/ + #define BOOST_PHOENIX_BINARY_OPERATORS(ops) \ namespace expression { \ BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_BINARY_EXPRESSION, _, ops) \ @@ -64,6 +117,7 @@ BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_BINARY_RULE, _, ops) \ } \ BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_GRAMMAR, _, ops) \ + BOOST_PP_SEQ_FOR_EACH(BOOST_PHOENIX_BINARY_FUNCTIONAL, _, ops) \ /**/ #endif diff --git a/include/boost/phoenix/operator/detail/undef_operator.hpp b/include/boost/phoenix/operator/detail/undef_operator.hpp index f797c5e..5068990 100644 --- a/include/boost/phoenix/operator/detail/undef_operator.hpp +++ b/include/boost/phoenix/operator/detail/undef_operator.hpp @@ -6,7 +6,9 @@ ==============================================================================*/ #undef BOOST_PHOENIX_UNARY_RULE +#undef BOOST_PHOENIX_UNARY_FUNCTIONAL #undef BOOST_PHOENIX_BINARY_RULE +#undef BOOST_PHOENIX_BINARY_FUNCTIONAL #undef BOOST_PHOENIX_UNARY_EXPRESSION #undef BOOST_PHOENIX_BINARY_EXPRESSION #undef BOOST_PHOENIX_GRAMMAR diff --git a/include/boost/phoenix/stl/algorithm/iteration.hpp b/include/boost/phoenix/stl/algorithm/iteration.hpp index 53ebed3..97b9416 100644 --- a/include/boost/phoenix/stl/algorithm/iteration.hpp +++ b/include/boost/phoenix/stl/algorithm/iteration.hpp @@ -39,7 +39,7 @@ namespace boost { namespace phoenix { }; template - F const & operator()(R& r, F const& fn) const + F const operator()(R& r, F const& fn) const { return std::for_each(detail::begin_(r), detail::end_(r), fn); } diff --git a/test/stdlib/cmath.cpp b/test/stdlib/cmath.cpp index 8d86a78..40dcf49 100644 --- a/test/stdlib/cmath.cpp +++ b/test/stdlib/cmath.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include int main()