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