--- ./boost/proto/debug.hpp 2010-06-11 00:03:27.000000000 +0900 +++ ./boost/proto/debug.hpp 2010-11-30 15:56:08.000000000 +0900 @@ -84,20 +84,44 @@ namespace hidden_detail_ { - struct ostream_wrapper - { - ostream_wrapper(std::ostream &sout) - : sout_(sout) - {} - - std::ostream &sout_; - }; - - template - std::ostream &operator <<(ostream_wrapper sout_wrap, Tag const &) - { - return sout_wrap.sout_ << typeid(Tag).name(); - } + // has_ostream_shift trait + struct yes_type { char x; }; + struct no_type { yes_type x[2]; }; + + template T fake(); + + no_type has_ostream_shift_test(...); + + template + typename boost::enable_if_c< sizeof( fake() << fake() ) + , yes_type >::type + has_ostream_shift_test(const T&); + + template + struct has_ostream_shift + : boost::mpl::bool_< + sizeof( has_ostream_shift_test(fake()) ) == sizeof( yes_type ) + > + {}; + + // output + template inline + void output_impl( std::ostream& os, const T& x, boost::mpl::true_ ) + { + os << x; + } + + template inline + void output_impl( std::ostream& os, const T& x, boost::mpl::false_ ) + { + os << BOOST_SP_TYPEID(T).name(); + } + + template inline + void output( std::ostream& os, const T& x ) + { + output_impl( os, x, has_ostream_shift() ); + } } namespace functional @@ -139,20 +163,22 @@ template void impl(Expr const &expr, mpl::long_<0>) const { - using namespace hidden_detail_; typedef typename tag_of::type tag; this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", "); - this->sout_ << tag() << "(" << proto::value(expr) << ")\n"; + hidden_detail_::output( this->sout_, tag() ); + this->sout_ << "("; + hidden_detail_::output( this->sout_, proto::value(expr) ); + this->sout_ << ")\n"; this->first_ = false; } template void impl(Expr const &expr, Arity) const { - using namespace hidden_detail_; typedef typename tag_of::type tag; this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", "); - this->sout_ << tag() << "(\n"; + hidden_detail_::output( this->sout_, tag() ); + this->sout_ << "(\n"; display_expr display(this->sout_, this->depth_ + 4); fusion::for_each(expr, display); this->sout_ << std::setw(this->depth_) << "" << ")\n";