sl@0: //----------------------------------------------------------------------------- sl@0: // boost-libs variant/libs/test/jobs.h header file sl@0: // See http://www.boost.org for updates, documentation, and revision history. sl@0: //----------------------------------------------------------------------------- sl@0: // sl@0: // Copyright (c) 2003 sl@0: // Eric Friedman, Itay Maman sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: #ifndef _JOBSH_INC_ sl@0: #define _JOBSH_INC_ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "boost/variant/variant_fwd.hpp" sl@0: #include "boost/variant/get.hpp" sl@0: #include "boost/variant/apply_visitor.hpp" sl@0: #include "boost/variant/static_visitor.hpp" sl@0: sl@0: #include "boost/detail/workaround.hpp" sl@0: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) sl@0: # pragma warn -lvc sl@0: #endif sl@0: sl@0: struct to_text : boost::static_visitor sl@0: { sl@0: private: // NO_FUNCTION_TEMPLATE_ORDERING workaround sl@0: sl@0: template < BOOST_VARIANT_ENUM_PARAMS(typename U) > sl@0: std::string to_text_impl( sl@0: const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) >& operand, long sl@0: ) const sl@0: { sl@0: std::ostringstream ost; sl@0: ost << "[V] " << boost::apply_visitor(to_text(), operand); sl@0: sl@0: return ost.str(); sl@0: } sl@0: sl@0: template sl@0: std::string to_text_impl(const Value& operand, int) const sl@0: { sl@0: std::ostringstream ost; sl@0: ost << "[V] " << operand; sl@0: sl@0: return ost.str(); sl@0: } sl@0: sl@0: public: sl@0: sl@0: template sl@0: std::string operator()(const T& operand) const sl@0: { sl@0: return to_text_impl(operand, 1L); sl@0: } sl@0: sl@0: }; sl@0: sl@0: struct total_sizeof : boost::static_visitor sl@0: { sl@0: total_sizeof() : total_(0) { } sl@0: sl@0: template sl@0: int operator()(const Value&) const sl@0: { sl@0: total_ += sizeof(Value); sl@0: return total_; sl@0: } sl@0: sl@0: int result() const sl@0: { sl@0: return total_; sl@0: } sl@0: sl@0: mutable int total_; sl@0: sl@0: }; // total_sizeof sl@0: sl@0: sl@0: sl@0: //Function object: sum_int sl@0: //Description: Compute total sum of a series of numbers, (when called successively) sl@0: //Use sizeof(T) if applied with a non-integral type sl@0: struct sum_int : boost::static_visitor sl@0: { sl@0: sl@0: sum_int() : total_(0) { } sl@0: sl@0: sl@0: template sl@0: struct int_to_type sl@0: { sl@0: BOOST_STATIC_CONSTANT(int, value = n); sl@0: }; sl@0: sl@0: //Integral type - add numerical value sl@0: template sl@0: void add(T t, int_to_type ) const sl@0: { sl@0: total_ += t; sl@0: } sl@0: sl@0: //Other types - add sizeof sl@0: template sl@0: void add(T& , int_to_type ) const sl@0: { sl@0: total_ += sizeof(T); sl@0: } sl@0: sl@0: template sl@0: int operator()(const T& t) const sl@0: { sl@0: //Int_to_type is used to select the correct add() overload sl@0: add(t, int_to_type::value>()); sl@0: return total_; sl@0: } sl@0: sl@0: int result() const sl@0: { sl@0: return total_; sl@0: } sl@0: sl@0: private: sl@0: mutable int total_; sl@0: sl@0: }; //sum_int sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: //Function object: sum_double sl@0: //Description: Compute total sum of a series of numbers, (when called successively) sl@0: //Accpetable input types: float, double (Other types are silently ignored) sl@0: struct sum_double : boost::static_visitor sl@0: { sl@0: sl@0: sum_double() : total_(0) { } sl@0: sl@0: void operator()(float value) const sl@0: { sl@0: total_ += value; sl@0: } sl@0: sl@0: void operator()(double value) const sl@0: { sl@0: total_ += value; sl@0: } sl@0: sl@0: template sl@0: void operator()(const T&) const sl@0: { sl@0: //Do nothing sl@0: } sl@0: sl@0: double result() const sl@0: { sl@0: return total_; sl@0: } sl@0: sl@0: private: sl@0: mutable double total_; sl@0: sl@0: }; //sum_double sl@0: sl@0: sl@0: sl@0: struct int_printer : boost::static_visitor sl@0: { sl@0: sl@0: int_printer(std::string prefix_s = "") : prefix_s_(prefix_s) { } sl@0: int_printer(const int_printer& other) : prefix_s_(other.prefix_s_) sl@0: { sl@0: ost_ << other.str(); sl@0: } sl@0: sl@0: std::string operator()(int x) const sl@0: { sl@0: ost_ << prefix_s_ << x; sl@0: return str(); sl@0: } sl@0: sl@0: std::string operator()(const std::vector& x) const sl@0: { sl@0: ost_ << prefix_s_; sl@0: sl@0: //Use another Int_printer object for printing a list of all integers sl@0: int_printer job(","); sl@0: ost_ << std::for_each(x.begin(), x.end(), job).str(); sl@0: sl@0: return str(); sl@0: } sl@0: sl@0: std::string str() const sl@0: { sl@0: return ost_.str(); sl@0: } sl@0: sl@0: private: sl@0: std::string prefix_s_; sl@0: mutable std::ostringstream ost_; sl@0: }; //int_printer sl@0: sl@0: sl@0: struct int_adder : boost::static_visitor<> sl@0: { sl@0: sl@0: int_adder(int rhs) : rhs_(rhs) { } sl@0: sl@0: result_type operator()(int& lhs) const sl@0: { sl@0: lhs += rhs_; sl@0: } sl@0: sl@0: template sl@0: result_type operator()(const T& ) const sl@0: { sl@0: //Do nothing sl@0: } sl@0: sl@0: int rhs_; sl@0: }; //int_adder sl@0: sl@0: sl@0: sl@0: sl@0: struct held_type_name : boost::static_visitor sl@0: { sl@0: sl@0: template sl@0: std::string operator()(const T& ) const sl@0: { sl@0: ost_ << '[' << typeid(T).name() << ']'; sl@0: return result(); sl@0: } sl@0: sl@0: std::string result() const sl@0: { sl@0: return ost_.str(); sl@0: } sl@0: sl@0: mutable std::ostringstream ost_; sl@0: sl@0: }; //held_type_name sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: struct spec sl@0: { sl@0: typedef T result; sl@0: }; sl@0: sl@0: template sl@0: inline void verify(VariantType& var, spec, std::string str = "") sl@0: { sl@0: const VariantType& cvar = var; sl@0: sl@0: BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S)); sl@0: BOOST_CHECK(cvar.type() == typeid(S)); sl@0: sl@0: // sl@0: // Check get<>() sl@0: // sl@0: BOOST_CHECK(boost::get(&var)); sl@0: BOOST_CHECK(boost::get(&cvar)); sl@0: sl@0: const S* ptr1 = 0; sl@0: const S* ptr2 = 0; sl@0: try sl@0: { sl@0: S& r = boost::get(var); sl@0: ptr1 = &r; sl@0: } sl@0: catch(boost::bad_get& ) sl@0: { sl@0: BOOST_ERROR( "get failed unexpectedly" ); sl@0: } sl@0: sl@0: try sl@0: { sl@0: const S& cr = boost::get(cvar); sl@0: ptr2 = &cr; sl@0: } sl@0: catch(boost::bad_get& ) sl@0: { sl@0: BOOST_ERROR( "get const failed unexpectedly" ); sl@0: } sl@0: sl@0: BOOST_CHECK(ptr1 != 0 && ptr2 == ptr1); sl@0: sl@0: // sl@0: // Check string content sl@0: // sl@0: if(str.length() > 0) sl@0: { sl@0: std::string temp = boost::apply_visitor(to_text(), cvar); sl@0: std::cout << "temp = " << temp << ", str = " << str << std::endl; sl@0: BOOST_CHECK(temp == str); sl@0: } sl@0: } sl@0: sl@0: sl@0: template sl@0: inline void verify_not(VariantType& var, spec) sl@0: { sl@0: const VariantType& cvar = var; sl@0: sl@0: BOOST_CHECK(cvar.type() != typeid(S)); sl@0: sl@0: // sl@0: // Check get<>() sl@0: // sl@0: BOOST_CHECK(!boost::get(&var)); sl@0: BOOST_CHECK(!boost::get(&cvar)); sl@0: sl@0: const S* ptr1 = 0; sl@0: const S* ptr2 = 0; sl@0: try sl@0: { sl@0: S& r = boost::get(var); // should throw sl@0: BOOST_ERROR( "get passed unexpectedly" ); sl@0: sl@0: ptr1 = &r; sl@0: } sl@0: catch(boost::bad_get& ) sl@0: { sl@0: // do nothing except pass-through sl@0: } sl@0: sl@0: try sl@0: { sl@0: const S& cr = boost::get(var); // should throw sl@0: BOOST_ERROR( "get const passed unexpectedly" ); sl@0: sl@0: ptr2 = &cr; sl@0: } sl@0: catch(boost::bad_get& ) sl@0: { sl@0: // do nothing except pass-through sl@0: } sl@0: sl@0: BOOST_CHECK(ptr1 == 0 && ptr2 == 0); sl@0: } sl@0: sl@0: sl@0: #endif //_JOBSH_INC_