Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:52

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004     Copyright (c)      2011 Bryce Lelbach
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #if !defined(BOOST_SPIRIT_UTREE_OPERATORS)
0010 #define BOOST_SPIRIT_UTREE_OPERATORS
0011 
0012 #if defined(BOOST_MSVC)
0013 # pragma warning(push)
0014 # pragma warning(disable: 4804)
0015 # pragma warning(disable: 4805)
0016 #endif
0017 
0018 #include <exception>
0019 #if !defined(BOOST_SPIRIT_DISABLE_UTREE_IO)
0020   #include <ios>
0021   #include <boost/io/ios_state.hpp>
0022 #endif
0023 #include <boost/spirit/home/support/utree/utree.hpp>
0024 #include <boost/preprocessor/cat.hpp>
0025 #include <boost/throw_exception.hpp>
0026 #include <boost/type_traits/is_arithmetic.hpp>
0027 #include <boost/type_traits/is_integral.hpp>
0028 
0029 namespace boost { namespace spirit 
0030 {
0031     // Relational operators
0032     bool operator==(utree const& a, utree const& b);
0033     bool operator<(utree const& a, utree const& b);
0034     bool operator!=(utree const& a, utree const& b);
0035     bool operator>(utree const& a, utree const& b);
0036     bool operator<=(utree const& a, utree const& b);
0037     bool operator>=(utree const& a, utree const& b);
0038 
0039 #if !defined(BOOST_SPIRIT_DISABLE_UTREE_IO)
0040     // output
0041     std::ostream& operator<<(std::ostream& out, utree const& x);
0042     std::ostream& operator<<(std::ostream& out, utree::invalid_type const& x);
0043     std::ostream& operator<<(std::ostream& out, utree::nil_type const& x);
0044 #endif
0045 
0046     // Logical operators
0047     utree operator&&(utree const& a, utree const& b);
0048     utree operator||(utree const& a, utree const& b);
0049     utree operator!(utree const& a);
0050 
0051     // Arithmetic operators
0052     utree operator+(utree const& a, utree const& b);
0053     utree operator-(utree const& a, utree const& b);
0054     utree operator*(utree const& a, utree const& b);
0055     utree operator/(utree const& a, utree const& b);
0056     utree operator%(utree const& a, utree const& b);
0057     utree operator-(utree const& a);
0058 
0059     // Bitwise operators
0060     utree operator&(utree const& a, utree const& b);
0061     utree operator|(utree const& a, utree const& b);
0062     utree operator^(utree const& a, utree const& b);
0063     utree operator<<(utree const& a, utree const& b);
0064     utree operator>>(utree const& a, utree const& b);
0065     utree operator~(utree const& a);
0066 
0067     // Implementation
0068     struct utree_is_equal
0069     {
0070         typedef bool result_type;
0071 
0072         template <typename A, typename B>
0073         bool dispatch(const A&, const B&, boost::mpl::false_) const
0074         {
0075             return false; // cannot compare different types by default
0076         }
0077 
0078         template <typename A, typename B>
0079         bool dispatch(const A& a, const B& b, boost::mpl::true_) const
0080         {
0081             return a == b; // for arithmetic types
0082         }
0083 
0084         template <typename A, typename B>
0085         bool operator()(const A& a, const B& b) const
0086         {
0087             return dispatch(a, b,
0088                 boost::mpl::and_<
0089                     boost::is_arithmetic<A>,
0090                     boost::is_arithmetic<B> >());
0091         }
0092 
0093         template <typename T>
0094         bool operator()(const T& a, const T& b) const
0095         {
0096             // This code works for lists
0097             return a == b;
0098         }
0099 
0100         template <typename Base, utree_type::info type_>
0101         bool operator()(
0102             basic_string<Base, type_> const& a,
0103             basic_string<Base, type_> const& b) const
0104         {
0105             return static_cast<Base const&>(a) == static_cast<Base const&>(b);
0106         }
0107 
0108         bool operator()(utree::invalid_type, utree::invalid_type) const
0109         {
0110             return true;
0111         }
0112 
0113         bool operator()(utree::nil_type, utree::nil_type) const
0114         {
0115             return true;
0116         }
0117 
0118         bool operator()(function_base const&, function_base const&) const
0119         {
0120             return false; // just don't allow comparison of functions
0121         }
0122     };
0123 
0124     struct utree_is_less_than
0125     {
0126         typedef bool result_type;
0127 
0128         template <typename A, typename B>
0129         bool dispatch(const A&, const B&, boost::mpl::false_) const
0130         {
0131             return false; // cannot compare different types by default
0132         }
0133 
0134         template <typename A, typename B>
0135         bool dispatch(const A& a, const B& b, boost::mpl::true_) const
0136         {
0137             return a < b; // for arithmetic types
0138         }
0139 
0140         template <typename A, typename B>
0141         bool operator()(const A& a, const B& b) const
0142         {
0143             return dispatch(a, b,
0144                 boost::mpl::and_<
0145                     boost::is_arithmetic<A>,
0146                     boost::is_arithmetic<B> >());
0147         }
0148 
0149         template <typename T>
0150         bool operator()(const T& a, const T& b) const
0151         {
0152             // This code works for lists
0153             return a < b;
0154         }
0155 
0156         template <typename Base, utree_type::info type_>
0157         bool operator()(
0158             basic_string<Base, type_> const& a,
0159             basic_string<Base, type_> const& b) const
0160         {
0161             return static_cast<Base const&>(a) < static_cast<Base const&>(b);
0162         }
0163 
0164         bool operator()(utree::invalid_type, utree::invalid_type) const
0165         {
0166             BOOST_THROW_EXCEPTION(bad_type_exception
0167               ("no less-than comparison for this utree type",
0168                utree_type::invalid_type));
0169             BOOST_UNREACHABLE_RETURN(false) // no less than comparison for nil
0170         }
0171 
0172         bool operator()(utree::nil_type, utree::nil_type) const
0173         {
0174             BOOST_THROW_EXCEPTION(bad_type_exception
0175               ("no less-than comparison for this utree type",
0176                utree_type::nil_type));
0177             BOOST_UNREACHABLE_RETURN(false) // no less than comparison for nil
0178         }
0179 
0180         bool operator()(any_ptr const&, any_ptr const&) const
0181         {
0182             BOOST_THROW_EXCEPTION(bad_type_exception
0183               ("no less-than comparison for this utree type",
0184                utree_type::any_type));
0185             BOOST_UNREACHABLE_RETURN(false) // no less than comparison for any_ptr
0186         }
0187 
0188         bool operator()(function_base const&, function_base const&) const
0189         {
0190             BOOST_THROW_EXCEPTION(bad_type_exception
0191               ("no less-than comparison for this utree type",
0192                utree_type::function_type));
0193             BOOST_UNREACHABLE_RETURN(false) // no less than comparison of functions
0194         }
0195     };
0196 
0197 #if !defined(BOOST_SPIRIT_DISABLE_UTREE_IO)
0198     struct utree_print
0199     {
0200         typedef void result_type;
0201 
0202         std::ostream& out;
0203         utree_print(std::ostream& out) : out(out) {}
0204 
0205         void operator()(utree::invalid_type) const
0206         {
0207             out << "<invalid> ";
0208         }
0209 
0210         void operator()(utree::nil_type) const
0211         {
0212             out << "<nil> ";
0213         }
0214 
0215         template <typename T>
0216         void operator()(T val) const
0217         {
0218             out << val << ' ';
0219         }
0220 
0221         void operator()(bool b) const
0222         {
0223             out << (b ? "true" : "false") << ' ';
0224         }
0225 
0226         void operator()(binary_range_type const& b) const
0227         {
0228             boost::io::ios_all_saver saver(out);
0229             out << "#";
0230             out.width(2);
0231             out.fill('0');
0232 
0233             typedef binary_range_type::const_iterator iterator;
0234             for (iterator i = b.begin(); i != b.end(); ++i)
0235                 out << std::hex << int((unsigned char)*i);
0236             out << "# ";
0237         }
0238 
0239         void operator()(utf8_string_range_type const& str) const
0240         {
0241             typedef utf8_string_range_type::const_iterator iterator;
0242             iterator i = str.begin();
0243             out << '"';
0244             for (; i != str.end(); ++i)
0245                 out << *i;
0246             out << "\" ";
0247         }
0248 
0249         void operator()(utf8_symbol_range_type const& str) const
0250         {
0251             typedef utf8_symbol_range_type::const_iterator iterator;
0252             iterator i = str.begin();
0253             for (; i != str.end(); ++i)
0254                 out << *i;
0255             out << ' ';
0256         }
0257 
0258         template <typename Iterator>
0259         void operator()(boost::iterator_range<Iterator> const& range) const
0260         {
0261             typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
0262             (*this)('(');
0263             for (iterator i = range.begin(); i != range.end(); ++i)
0264             {
0265                 boost::spirit::utree::visit(*i, *this);
0266             }
0267             (*this)(')');
0268         }
0269 
0270         void operator()(any_ptr const&) const
0271         {
0272             return (*this)("<pointer>");
0273         }
0274 
0275         void operator()(function_base const&) const
0276         {
0277             return (*this)("<function>");
0278         }
0279     };
0280 #endif
0281 
0282     template <typename Base>
0283     struct logical_function
0284     {
0285         typedef utree result_type;
0286 
0287         // We assume anything except false is true
0288 
0289         // binary
0290         template <typename A, typename B>
0291         utree operator()(A const& a, B const& b) const
0292         {
0293             return dispatch(a, b
0294               , boost::is_arithmetic<A>()
0295               , boost::is_arithmetic<B>());
0296         }
0297 
0298         // binary
0299         template <typename A, typename B>
0300         utree dispatch(A const& a, B const& b, mpl::true_, mpl::true_) const
0301         {
0302             return Base::eval(a, b); // for arithmetic types
0303         }
0304 
0305         // binary
0306         template <typename A, typename B>
0307         utree dispatch(A const&, B const& b, mpl::false_, mpl::true_) const
0308         {
0309             return Base::eval(true, b);
0310         }
0311 
0312         // binary
0313         template <typename A, typename B>
0314         utree dispatch(A const& a, B const&, mpl::true_, mpl::false_) const
0315         {
0316             return Base::eval(a, true);
0317         }
0318 
0319         // binary
0320         template <typename A, typename B>
0321         utree dispatch(A const&, B const&, mpl::false_, mpl::false_) const
0322         {
0323             return Base::eval(true, true);
0324         }
0325         
0326         // unary
0327         template <typename A>
0328         utree operator()(A const& a) const
0329         {
0330             return dispatch(a, boost::is_arithmetic<A>());
0331         }
0332 
0333         // unary
0334         template <typename A>
0335         utree dispatch(A const& a, mpl::true_) const
0336         {
0337             return Base::eval(a);
0338         }
0339 
0340         // unary
0341         template <typename A>
0342         utree dispatch(A const&, mpl::false_) const
0343         {
0344             return Base::eval(true);
0345         }
0346     };
0347 
0348     template <typename Base>
0349     struct arithmetic_function
0350     {
0351         typedef utree result_type;
0352 
0353         template <typename A, typename B>
0354         utree dispatch(A const&, B const&, boost::mpl::false_) const
0355         {
0356             return utree(); // cannot apply to non-arithmetic types
0357         }
0358 
0359         template <typename A, typename B>
0360         utree dispatch(A const& a, B const& b, boost::mpl::true_) const
0361         {
0362             return Base::eval(a, b); // for arithmetic types
0363         }
0364 
0365         // binary
0366         template <typename A, typename B>
0367         utree operator()(A const& a, B const& b) const
0368         {
0369             return dispatch(a, b,
0370                 boost::mpl::and_<
0371                     boost::is_arithmetic<A>,
0372                     boost::is_arithmetic<B> >());
0373         }
0374 
0375         template <typename A>
0376         utree dispatch(A const&, boost::mpl::false_) const
0377         {
0378             return utree(); // cannot apply to non-arithmetic types
0379         }
0380 
0381         template <typename A>
0382         utree dispatch(A const& a, boost::mpl::true_) const
0383         {
0384             return Base::eval(a); // for arithmetic types
0385         }
0386 
0387         // unary
0388         template <typename A>
0389         utree operator()(A const& a) const
0390         {
0391             return dispatch(a, boost::is_arithmetic<A>());
0392         }
0393     };
0394 
0395     template <typename Base>
0396     struct integral_function
0397     {
0398         typedef utree result_type;
0399 
0400         template <typename A, typename B>
0401         utree dispatch(A const&, B const&, boost::mpl::false_) const
0402         {
0403             return utree(); // cannot apply to non-integral types
0404         }
0405 
0406         template <typename A, typename B>
0407         utree dispatch(A const& a, B const& b, boost::mpl::true_) const
0408         {
0409             return Base::eval(a, b); // for integral types
0410         }
0411 
0412         // binary
0413         template <typename A, typename B>
0414         utree operator()(A const& a, B const& b) const
0415         {
0416             return dispatch(a, b,
0417                 boost::mpl::and_<
0418                     boost::is_integral<A>,
0419                     boost::is_integral<B> >());
0420         }
0421 
0422         template <typename A>
0423         utree dispatch(A const&, boost::mpl::false_) const
0424         {
0425             return utree(); // cannot apply to non-integral types
0426         }
0427 
0428         template <typename A>
0429         utree dispatch(A const& a, boost::mpl::true_) const
0430         {
0431             return Base::eval(a); // for integral types
0432         }
0433 
0434         // unary
0435         template <typename A>
0436         utree operator()(A const& a) const
0437         {
0438             return dispatch(a, boost::is_integral<A>());
0439         }
0440     };
0441 
0442 #define BOOST_SPIRIT_UTREE_CREATE_FUNCTION_BINARY                             \
0443         template <typename Lhs, typename Rhs>                                 \
0444         static utree eval(Lhs const& a, Rhs const& b)                         \
0445         /***/
0446 
0447 #define BOOST_SPIRIT_UTREE_CREATE_FUNCTION_UNARY                              \
0448         template <typename Operand>                                           \
0449         static utree eval(Operand const& a)                                   \
0450         /***/
0451 
0452 #define BOOST_SPIRIT_UTREE_CREATE_FUNCTION(arity, name, expr, base)           \
0453     struct BOOST_PP_CAT(function_impl_, name)                                 \
0454     {                                                                         \
0455         BOOST_SPIRIT_UTREE_CREATE_FUNCTION_##arity                            \
0456         {                                                                     \
0457             return utree(expr);                                               \
0458         }                                                                     \
0459     };                                                                        \
0460     base<BOOST_PP_CAT(function_impl_, name)> const                            \
0461         BOOST_PP_CAT(base, BOOST_PP_CAT(_, name)) = {};                       \
0462     /***/
0463 
0464 #define BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(arity, name, expr)      \
0465     BOOST_SPIRIT_UTREE_CREATE_FUNCTION(arity, name, expr, arithmetic_function)\
0466     /***/
0467 
0468 #define BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(arity, name, expr)        \
0469     BOOST_SPIRIT_UTREE_CREATE_FUNCTION(arity, name, expr, integral_function)  \
0470     /***/
0471 
0472 #define BOOST_SPIRIT_UTREE_CREATE_LOGICAL_FUNCTION(arity, name, expr)         \
0473     BOOST_SPIRIT_UTREE_CREATE_FUNCTION(arity, name, expr, logical_function)   \
0474     /***/
0475 
0476     inline bool operator==(utree const& a, utree const& b)
0477     {
0478         return utree::visit(a, b, utree_is_equal());
0479     }
0480 
0481     inline bool operator<(utree const& a, utree const& b)
0482     {
0483         return utree::visit(a, b, utree_is_less_than());
0484     }
0485 
0486     inline bool operator!=(utree const& a, utree const& b)
0487     {
0488         return !(a == b);
0489     }
0490 
0491     inline bool operator>(utree const& a, utree const& b)
0492     {
0493         return b < a;
0494     }
0495 
0496     inline bool operator<=(utree const& a, utree const& b)
0497     {
0498         return !(b < a);
0499     }
0500 
0501     inline bool operator>=(utree const& a, utree const& b)
0502     {
0503         return !(a < b);
0504     }
0505 
0506 #if !defined(BOOST_SPIRIT_DISABLE_UTREE_IO)
0507     inline std::ostream& operator<<(std::ostream& out, utree const& x)
0508     {
0509         utree::visit(x, utree_print(out));
0510         return out;
0511     }
0512 
0513     inline std::ostream& operator<<(std::ostream& out, utree::invalid_type const&)
0514     {
0515         return out;
0516     }
0517 
0518     inline std::ostream& operator<<(std::ostream& out, utree::nil_type const&)
0519     {
0520         return out;
0521     }
0522 #endif
0523 
0524     BOOST_SPIRIT_UTREE_CREATE_LOGICAL_FUNCTION(BINARY, and_, a&&b)
0525     BOOST_SPIRIT_UTREE_CREATE_LOGICAL_FUNCTION(BINARY, or_,  a||b)
0526     BOOST_SPIRIT_UTREE_CREATE_LOGICAL_FUNCTION(UNARY,  not_, !a)
0527 
0528     BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(BINARY, plus,    a+b)
0529     BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(BINARY, minus,   a-b)
0530     BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(BINARY, times,   a*b)
0531     BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(BINARY, divides, a/b)
0532     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION  (BINARY, modulus, a%b)
0533     BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION(UNARY,  negate,  -a)
0534 
0535     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(BINARY, bitand_,     a&b)
0536     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(BINARY, bitor_,      a|b)
0537     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(BINARY, bitxor_,     a^b)
0538     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(BINARY, shift_left,  a<<b)
0539     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(BINARY, shift_right, a>>b)
0540     BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION(UNARY,  invert,      ~a)
0541 
0542     // avoid `'~' on an expression of type bool` warning
0543     template <> inline utree function_impl_invert::eval<bool>(bool const& a)
0544     {
0545         return utree(!a);
0546     }
0547 
0548 #undef BOOST_SPIRIT_UTREE_CREATE_FUNCTION_BINARY
0549 #undef BOOST_SPIRIT_UTREE_CREATE_FUNCTION_UNARY
0550 #undef BOOST_SPIRIT_UTREE_CREATE_FUNCTION
0551 #undef BOOST_SPIRIT_UTREE_CREATE_LOGICAL_FUNCTION
0552 #undef BOOST_SPIRIT_UTREE_CREATE_INTEGRAL_FUNCTION
0553 #undef BOOST_SPIRIT_UTREE_CREATE_ARITHMETIC_FUNCTION
0554 
0555     inline utree operator&&(utree const& a, utree const& b)
0556     {
0557           return utree::visit(a, b, logical_function_and_);
0558     }
0559 
0560     inline utree operator||(utree const& a, utree const& b)
0561     {
0562         return utree::visit(a, b, logical_function_or_);
0563     }
0564 
0565     inline utree operator!(utree const& a)
0566     {
0567         return utree::visit(a, logical_function_not_);
0568     }
0569 
0570     inline utree operator+(utree const& a, utree const& b)
0571     {
0572         utree r = utree::visit(a, b, arithmetic_function_plus);
0573         if (r.which() == utree_type::invalid_type)
0574         {
0575             BOOST_THROW_EXCEPTION(bad_type_exception
0576               ("addition performed on non-arithmetic utree types",
0577                a.which(), b.which()));
0578         } 
0579         return r;
0580     }
0581 
0582     inline utree operator-(utree const& a, utree const& b)
0583     {
0584         utree r = utree::visit(a, b, arithmetic_function_minus);
0585         if (r.which() == utree_type::invalid_type)
0586         {
0587             BOOST_THROW_EXCEPTION(bad_type_exception
0588               ("subtraction performed on non-arithmetic utree types",
0589                a.which(), b.which()));
0590         } 
0591         return r;
0592     }
0593 
0594     inline utree operator*(utree const& a, utree const& b)
0595     {
0596         utree r = utree::visit(a, b, arithmetic_function_times);
0597         if (r.which() == utree_type::invalid_type)
0598         {
0599             BOOST_THROW_EXCEPTION(bad_type_exception
0600               ("multiplication performed on non-arithmetic utree types",
0601                a.which(), b.which()));
0602         } 
0603         return r;
0604     }
0605 
0606     inline utree operator/(utree const& a, utree const& b)
0607     {
0608         utree r = utree::visit(a, b, arithmetic_function_divides);
0609         if (r.which() == utree_type::invalid_type)
0610         {
0611             BOOST_THROW_EXCEPTION(bad_type_exception
0612               ("division performed on non-arithmetic utree types",
0613                a.which(), b.which()));
0614         } 
0615         return r;
0616     }
0617 
0618     inline utree operator%(utree const& a, utree const& b)
0619     {
0620         utree r = utree::visit(a, b, integral_function_modulus);
0621         if (r.which() == utree_type::invalid_type)
0622         {
0623             BOOST_THROW_EXCEPTION(bad_type_exception
0624               ("modulos performed on non-integral utree types",
0625                a.which(), b.which()));
0626         } 
0627         return r;
0628     }
0629 
0630     inline utree operator-(utree const& a)
0631     {
0632         utree r = utree::visit(a, arithmetic_function_negate);
0633         if (r.which() == utree_type::invalid_type)
0634         {
0635             BOOST_THROW_EXCEPTION(bad_type_exception
0636               ("negation performed on non-arithmetic utree type",
0637                a.which()));
0638         } 
0639         return r;
0640     }
0641 
0642     inline utree operator&(utree const& a, utree const& b)
0643     {
0644         utree r = utree::visit(a, b, integral_function_bitand_);
0645         if (r.which() == utree_type::invalid_type)
0646         {
0647             BOOST_THROW_EXCEPTION(bad_type_exception
0648               ("bitwise and performed on non-integral utree types",
0649                a.which(), b.which()));
0650         } 
0651         return r;
0652     }
0653 
0654     inline utree operator|(utree const& a, utree const& b)
0655     {
0656         utree r = utree::visit(a, b, integral_function_bitor_);
0657         if (r.which() == utree_type::invalid_type)
0658         {
0659             BOOST_THROW_EXCEPTION(bad_type_exception
0660               ("bitwise or performed on non-integral utree types",
0661                a.which(), b.which()));
0662         } 
0663         return r;
0664     }
0665 
0666     inline utree operator^(utree const& a, utree const& b)
0667     {
0668         utree r = utree::visit(a, b, integral_function_bitxor_);
0669         if (r.which() == utree_type::invalid_type)
0670         {
0671             BOOST_THROW_EXCEPTION(bad_type_exception
0672               ("bitwise xor performed on non-integral utree types",
0673                a.which(), b.which()));
0674         } 
0675         return r;
0676     }
0677 
0678     inline utree operator<<(utree const& a, utree const& b)
0679     {
0680         utree r = utree::visit(a, b, integral_function_shift_left);
0681         if (r.which() == utree_type::invalid_type)
0682         {
0683             BOOST_THROW_EXCEPTION(bad_type_exception
0684               ("left shift performed on non-integral utree types",
0685                a.which(), b.which()));
0686         } 
0687         return r;
0688     }
0689 
0690     inline utree operator>>(utree const& a, utree const& b)
0691     {
0692         utree r = utree::visit(a, b, integral_function_shift_right);
0693         if (r.which() == utree_type::invalid_type)
0694         {
0695             BOOST_THROW_EXCEPTION(bad_type_exception
0696               ("right shift performed on non-integral utree types",
0697                a.which(), b.which()));
0698         } 
0699         return r;
0700     }
0701 
0702     inline utree operator~(utree const& a)
0703     {
0704         utree r = utree::visit(a, integral_function_invert);
0705         if (r.which() == utree_type::invalid_type)
0706         {
0707             BOOST_THROW_EXCEPTION(bad_type_exception
0708               ("inversion performed on non-integral utree type",
0709                a.which()));
0710         } 
0711         return r;
0712     }
0713 }}
0714 
0715 #if defined(BOOST_MSVC)
0716 # pragma warning(pop)
0717 #endif
0718 
0719 #endif