diff options
Diffstat (limited to 'src/boost/libs/variant/test/jobs.h')
-rw-r--r-- | src/boost/libs/variant/test/jobs.h | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/src/boost/libs/variant/test/jobs.h b/src/boost/libs/variant/test/jobs.h new file mode 100644 index 000000000..9b965554a --- /dev/null +++ b/src/boost/libs/variant/test/jobs.h @@ -0,0 +1,335 @@ +//----------------------------------------------------------------------------- +// 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 <algorithm> +#include <iostream> +#include <sstream> +#include <string> +#include <typeinfo> +#include <vector> + +#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<std::string> +{ +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 <typename Value> + std::string to_text_impl(const Value& operand, int) const + { + std::ostringstream ost; + ost << "[V] " << operand; + + return ost.str(); + } + +public: + + template <typename T> + std::string operator()(const T& operand) const + { + return to_text_impl(operand, 1L); + } + +}; + +struct total_sizeof : boost::static_visitor<int> +{ + total_sizeof() : total_(0) { } + + template<class Value> + 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<int> +{ + + sum_int() : total_(0) { } + + + template<int n> + struct int_to_type + { + BOOST_STATIC_CONSTANT(int, value = n); + }; + + //Integral type - add numerical value + template<typename T> + void add(T t, int_to_type<true> ) const + { + total_ += t; + } + + //Other types - add sizeof<T> + template<typename T> + void add(T& , int_to_type<false> ) const + { + total_ += sizeof(T); + } + + template<typename T> + int operator()(const T& t) const + { + //Int_to_type is used to select the correct add() overload + add(t, int_to_type<boost::is_integral<T>::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<double> +{ + + sum_double() : total_(0) { } + + void operator()(float value) const + { + total_ += value; + } + + void operator()(double value) const + { + total_ += value; + } + + template<typename T> + void operator()(const T&) const + { + //Do nothing + } + + double result() const + { + return total_; + } + +private: + mutable double total_; + +}; //sum_double + + + +struct int_printer : boost::static_visitor<std::string> +{ + + 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<int>& 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<typename T> + result_type operator()(const T& ) const + { + //Do nothing + } + + int rhs_; +}; //int_adder + + + +template<typename T> +struct spec +{ + typedef T result; +}; + +template<typename VariantType, typename S> +inline void verify(VariantType& var, spec<S>, 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<S>()); + + // + // Check get<>() + // + BOOST_TEST(boost::get<S>(&var)); + BOOST_TEST(boost::get<S>(&cvar)); + + const S* ptr1 = 0; + const S* ptr2 = 0; + try + { + S& r = boost::get<S>(var); + ptr1 = &r; + } + catch(const boost::bad_get& ) + { + BOOST_ERROR( "get<S> failed unexpectedly" ); + } + + try + { + const S& cr = boost::get<S>(cvar); + ptr2 = &cr; + } + catch(const boost::bad_get& ) + { + BOOST_ERROR( "get<S> 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<typename VariantType, typename S> +inline void verify_not(VariantType& var, spec<S>) +{ + const VariantType& cvar = var; + + BOOST_TEST(cvar.type() != boost::typeindex::type_id<S>()); + + // + // Check get<>() + // + BOOST_TEST(!boost::get<S>(&var)); + BOOST_TEST(!boost::get<S>(&cvar)); + + const S* ptr1 = 0; + const S* ptr2 = 0; + try + { + S& r = boost::get<S>(var); // should throw + BOOST_ERROR( "get<S> passed unexpectedly" ); + + ptr1 = &r; + } + catch(const boost::bad_get& ) + { + // do nothing except pass-through + } + + try + { + const S& cr = boost::get<S>(var); // should throw + BOOST_ERROR( "get<S> const passed unexpectedly" ); + + ptr2 = &cr; + } + catch(const boost::bad_get& ) + { + // do nothing except pass-through + } + + BOOST_TEST(ptr1 == 0 && ptr2 == 0); +} + + +#endif //_JOBSH_INC_ |