diff --git a/sprout/weed/attr_cnv.hpp b/sprout/weed/attr_cnv.hpp index 2109dbf5..9fd2222a 100644 --- a/sprout/weed/attr_cnv.hpp +++ b/sprout/weed/attr_cnv.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/sprout/weed/attr_cnv/negate.hpp b/sprout/weed/attr_cnv/negate.hpp new file mode 100644 index 00000000..3d62685b --- /dev/null +++ b/sprout/weed/attr_cnv/negate.hpp @@ -0,0 +1,28 @@ +#ifndef SPROUT_WEED_ATTR_CNV_NEGATE_HPP +#define SPROUT_WEED_ATTR_CNV_NEGATE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + namespace attr_cnv { + // + // negate + // + // !unused -> unused + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::weed::traits::is_unused::value, + typename sprout::weed::attr_cnv::result_of::negate::type + >::type negate(T const& t, bool cond) { + return sprout::weed::unused(); + } + } // namespace attr_cnv + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_ATTR_CNV_NEGATE_HPP diff --git a/sprout/weed/attr_cnv/result_of.hpp b/sprout/weed/attr_cnv/result_of.hpp index 0e672018..953b3559 100644 --- a/sprout/weed/attr_cnv/result_of.hpp +++ b/sprout/weed/attr_cnv/result_of.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/sprout/weed/attr_cnv/result_of/negate.hpp b/sprout/weed/attr_cnv/result_of/negate.hpp new file mode 100644 index 00000000..226d9848 --- /dev/null +++ b/sprout/weed/attr_cnv/result_of/negate.hpp @@ -0,0 +1,34 @@ +#ifndef SPROUT_WEED_ATTR_CNV_RESULT_OF_NEGATE_HPP +#define SPROUT_WEED_ATTR_CNV_RESULT_OF_NEGATE_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace weed { + namespace attr_cnv { + namespace result_of { + // + // negate + // + template + struct negate; + // -unused -> unused + template + struct negate< + T, + typename std::enable_if< + sprout::weed::traits::is_unused::value + >::type + > { + public: + typedef sprout::weed::unused type; + }; + } // namespace result_of + } // namespace attr_cnv + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_ATTR_CNV_RESULT_OF_NEGATE_HPP diff --git a/sprout/weed/context/parse_context/operator.hpp b/sprout/weed/context/parse_context/operator.hpp index e2b4ce25..97e53ae9 100644 --- a/sprout/weed/context/parse_context/operator.hpp +++ b/sprout/weed/context/parse_context/operator.hpp @@ -3,11 +3,13 @@ #include #include +#include #include #include #include #include #include +#include #include #endif // #ifndef SPROUT_WEED_CONTEXT_PARSE_CONTEXT_OPERATOR_HPP diff --git a/sprout/weed/context/parse_context/operator/minus.hpp b/sprout/weed/context/parse_context/operator/minus.hpp new file mode 100644 index 00000000..3a4a32d8 --- /dev/null +++ b/sprout/weed/context/parse_context/operator/minus.hpp @@ -0,0 +1,67 @@ +#ifndef SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_MINUS_HPP +#define SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_MINUS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // parse_context::eval + // + template + template + struct parse_context::eval< + Expr, + typename std::enable_if< + std::is_same< + typename sprout::weed::traits::tag_of::type, + sprout::weed::tag::minus + >::value + >::type + > { + private: + typedef sprout::weed::parse_context context_type; + public: + typedef typename sprout::weed::traits::attribute_of::type attribute_type; + typedef sprout::weed::eval_result result_type; + private: + template + SPROUT_CONSTEXPR result_type call_1( + typename Expr::args_type const& args, + context_type const& ctx, + Result1 const& res + ) const + { + return res.success() && !sprout::weed::eval(sprout::tuples::get<1>(args), ctx).success() + ? res + : result_type(false, ctx.begin(), attribute_type(), ctx) + ; + } + SPROUT_CONSTEXPR result_type call( + typename Expr::args_type const& args, + context_type const& ctx + ) const + { + return call_1(args, ctx, sprout::weed::eval(sprout::tuples::get<0>(args), ctx)); + } + public: + SPROUT_CONSTEXPR result_type operator()( + Expr const& expr, + context_type const& ctx + ) const + { + return call(expr.args(), ctx); + } + }; + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_MINUS_HPP diff --git a/sprout/weed/context/parse_context/operator/negate.hpp b/sprout/weed/context/parse_context/operator/negate.hpp new file mode 100644 index 00000000..d74606f9 --- /dev/null +++ b/sprout/weed/context/parse_context/operator/negate.hpp @@ -0,0 +1,62 @@ +#ifndef SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_NEGATE_HPP +#define SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_NEGATE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // parse_context::eval + // + template + template + struct parse_context::eval< + Expr, + typename std::enable_if< + std::is_same< + typename sprout::weed::traits::tag_of::type, + sprout::weed::tag::negate + >::value + >::type + > { + private: + typedef sprout::weed::parse_context context_type; + public: + typedef typename sprout::weed::traits::attribute_of::type attribute_type; + typedef sprout::weed::eval_result result_type; + private: + template + SPROUT_CONSTEXPR result_type call( + context_type const& ctx, + Result const& res + ) const + { + return result_type( + true, + res.current(), + sprout::weed::attr_cnv::negate(res.attr(), res.success()), + res.success() ? context_type(ctx, res.current()) : ctx + ); + } + public: + SPROUT_CONSTEXPR result_type operator()( + Expr const& expr, + context_type const& ctx + ) const + { + return call(ctx, sprout::weed::eval(sprout::tuples::get<0>(expr.args()), ctx)); + } + }; + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_CONTEXT_PARSE_CONTEXT_TERMINAL_OPERATOR_NEGATE_HPP diff --git a/sprout/weed/expr/tag.hpp b/sprout/weed/expr/tag.hpp index fb6286b6..384388c5 100644 --- a/sprout/weed/expr/tag.hpp +++ b/sprout/weed/expr/tag.hpp @@ -8,11 +8,13 @@ namespace sprout { namespace tag { struct terminal {}; struct unary_plus {}; + struct negate {}; struct dereference {}; struct address_of {}; struct logical_not {}; struct shift_left {}; struct modulus {}; + struct minus {}; struct bitwise_or {}; } // namespace tag } // namespace weed diff --git a/sprout/weed/operator.hpp b/sprout/weed/operator.hpp index 0c56f223..ba4e1473 100644 --- a/sprout/weed/operator.hpp +++ b/sprout/weed/operator.hpp @@ -3,11 +3,13 @@ #include #include +#include #include #include #include #include #include +#include #include #endif // #ifndef SPROUT_WEED_OPERATOR_HPP diff --git a/sprout/weed/operator/address_of.hpp b/sprout/weed/operator/address_of.hpp index 5df73480..5c4b66e0 100644 --- a/sprout/weed/operator/address_of.hpp +++ b/sprout/weed/operator/address_of.hpp @@ -26,7 +26,7 @@ namespace sprout { SPROUT_CONSTEXPR inline typename sprout::weed::traits::expr_of< sprout::weed::tag::address_of, Arg - >::type operator!(Arg&& arg) { + >::type operator&(Arg&& arg) { return sprout::weed::make_expr( sprout::forward(arg) ); diff --git a/sprout/weed/operator/minus.hpp b/sprout/weed/operator/minus.hpp new file mode 100644 index 00000000..9c73d7cc --- /dev/null +++ b/sprout/weed/operator/minus.hpp @@ -0,0 +1,43 @@ +#ifndef SPROUT_WEED_OPERATOR_MINUS_HPP +#define SPROUT_WEED_OPERATOR_MINUS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // operator- + // + template< + typename Arg1, + typename Arg2, + typename = typename std::enable_if< + sprout::weed::traits::is_parser< + typename sprout::weed::detail::uncvref::type + >::value + && sprout::weed::traits::is_parser< + typename sprout::weed::detail::uncvref::type + >::value + >::type + > + SPROUT_CONSTEXPR inline typename sprout::weed::traits::expr_of< + sprout::weed::tag::minus, + Arg1, + Arg2 + >::type operator-(Arg1&& arg1, Arg2&& arg2) { + return sprout::weed::make_expr( + sprout::forward(arg1), + sprout::forward(arg2) + ); + } + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_OPERATOR_MINUS_HPP diff --git a/sprout/weed/operator/negate.hpp b/sprout/weed/operator/negate.hpp new file mode 100644 index 00000000..c8e3be79 --- /dev/null +++ b/sprout/weed/operator/negate.hpp @@ -0,0 +1,37 @@ +#ifndef SPROUT_WEED_OPERATOR_NEGATE_HPP +#define SPROUT_WEED_OPERATOR_NEGATE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // operator- + // + template< + typename Arg, + typename = typename std::enable_if< + sprout::weed::traits::is_parser< + typename sprout::weed::detail::uncvref::type + >::value + >::type + > + SPROUT_CONSTEXPR inline typename sprout::weed::traits::expr_of< + sprout::weed::tag::negate, + Arg + >::type operator-(Arg&& arg) { + return sprout::weed::make_expr( + sprout::forward(arg) + ); + } + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_OPERATOR_NEGATE_HPP diff --git a/sprout/weed/traits/parser/attribute_of.hpp b/sprout/weed/traits/parser/attribute_of.hpp index db74f5e4..52e4a85c 100644 --- a/sprout/weed/traits/parser/attribute_of.hpp +++ b/sprout/weed/traits/parser/attribute_of.hpp @@ -71,6 +71,12 @@ namespace sprout { > {}; template + struct attribute_of, Iterator, Context> + : public sprout::weed::attr_cnv::result_of::negate< + typename sprout::weed::traits::attribute_of::type + > + {}; + template struct attribute_of, Iterator, Context> : public sprout::weed::attr_cnv::result_of::times< sprout::weed::traits::limit_of::value, @@ -102,6 +108,11 @@ namespace sprout { > {}; template + struct attribute_of, Iterator, Context> { + public: + typedef typename sprout::weed::traits::attribute_of::type type; + }; + template struct attribute_of, Iterator, Context> : public sprout::weed::attr_cnv::result_of::bitwise_or< typename sprout::weed::traits::attribute_of::type,