//////////////////////////////////////////////////////////////////////////// // complement_compiler.hpp // // Copyright 2004 Eric Niebler. Distributed under the 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_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005 #define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005 #include #include #include #include #include #include #include #include #include namespace boost { namespace xpressive { namespace detail { /////////////////////////////////////////////////////////////////////////////// // complement // the result of applying operator~ to various expressions template struct complement { // If your compile breaks here, then you are applying the complement operator ~ // to something that does not support it. For instance, ~(_ >> 'a') will trigger this // assertion because the sub-expression (_ >> 'a') has no complement. BOOST_MPL_ASSERT((never_true)); }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, proto::noop_tag>, Visitor> { typedef proto::unary_op, proto::noop_tag> type; static type const call(proto::unary_op, proto::noop_tag> const &op, Visitor &) { literal_placeholder literal = proto::arg(op).ch_; return proto::noop(literal); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, Visitor> { typedef proto::unary_op, proto::noop_tag> type; static type const call(proto::unary_op const &op, Visitor &) { literal_placeholder literal = proto::arg(op); return proto::noop(literal); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, proto::noop_tag>, Visitor> { typedef proto::unary_op, proto::noop_tag> type; static type const call(proto::unary_op, proto::noop_tag> const &op, Visitor &) { set_matcher set = proto::arg(op); set.complement(); return proto::noop(set); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, Visitor> { typedef proto::unary_op type; static type const call(proto::unary_op const &op, Visitor &) { posix_charset_placeholder posix = proto::arg(op); posix.not_ = !posix.not_; return proto::noop(posix); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, Visitor> { typedef typename charset_transform::BOOST_NESTED_TEMPLATE apply < proto::binary_op , dont_care , Visitor >::type type; static type call(proto::binary_op const &op, Visitor &visitor) { return charset_transform::call(op, dont_care(), visitor, true); } }; /////////////////////////////////////////////////////////////////////////////// // for complementing a list-initialized set, as in ~(set= 'a','b','c') template struct complement, Visitor> { // First, convert the parse tree into a set_matcher typedef typename proto::compiler::BOOST_NESTED_TEMPLATE apply < proto::binary_op , dont_care , Visitor >::type set_matcher; typedef proto::unary_op type; static type const call(proto::binary_op const &op, Visitor &visitor) { set_matcher set(proto::compile(op, dont_care(), visitor, lst_tag())); set.complement(); return proto::noop(set); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement >, Visitor> { typedef proto::unary_op > type; static type call(proto::unary_op > const &op, Visitor &) { return proto::make_op >(proto::arg(op)); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement >, Visitor> { typedef proto::unary_op > type; static type call(proto::unary_op > const &op, Visitor &) { return proto::make_op >(proto::arg(op)); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement >, proto::noop_tag>, Visitor> { typedef proto::unary_op >, proto::noop_tag> type; static type call(proto::unary_op >, proto::noop_tag> const &, Visitor &) { return proto::noop(assert_word_placeholder >()); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement { typedef proto::binary_op < proto::unary_op > , proto::unary_op , proto::right_shift_tag > type; static type call(logical_newline_xpression const &op, Visitor &) { return proto::make_op >(op) >> proto::noop(any_matcher()); } }; /////////////////////////////////////////////////////////////////////////////// // complementing a complement is a no-op template struct complement, Visitor> { typedef Arg type; static Arg const &call(proto::unary_op const &op, Visitor &) { return proto::arg(op); } }; /////////////////////////////////////////////////////////////////////////////// // template struct complement, proto::noop_tag>, Visitor> { typedef proto::unary_op, proto::noop_tag> type; static type const call(proto::unary_op, proto::noop_tag> const &op, Visitor &) { range_placeholder rng = proto::arg(op); rng.not_ = !rng.not_; return proto::noop(rng); } }; /////////////////////////////////////////////////////////////////////////////// // complement_transform struct complement_transform { template struct apply { typedef typename complement::type, Visitor>::type type; }; template static typename complement::type, Visitor>::type call(Op const &op, State const &, Visitor &visitor) { return complement::type, Visitor>::call(proto::arg(op), visitor); } }; }}} namespace boost { namespace proto { template<> struct compiler : transform_compiler { }; }} #endif