os/ossrv/stdcpp/tsrc/Boost_test/variant/inc/jobs.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 //-----------------------------------------------------------------------------
     2 // boost-libs variant/libs/test/jobs.h header file
     3 // See http://www.boost.org for updates, documentation, and revision history.
     4 //-----------------------------------------------------------------------------
     5 //
     6 // Copyright (c) 2003
     7 // Eric Friedman, Itay Maman
     8 //
     9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
    12 
    13 #ifndef _JOBSH_INC_
    14 #define _JOBSH_INC_
    15 
    16 #include <algorithm>
    17 #include <iostream>
    18 #include <sstream>
    19 #include <string>
    20 #include <typeinfo>
    21 #include <vector>
    22 
    23 #include "boost/variant/variant_fwd.hpp"
    24 #include "boost/variant/get.hpp"
    25 #include "boost/variant/apply_visitor.hpp"
    26 #include "boost/variant/static_visitor.hpp"
    27 
    28 #include "boost/detail/workaround.hpp"
    29 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
    30 #    pragma warn -lvc
    31 #endif
    32 
    33 struct to_text : boost::static_visitor<std::string>
    34 {
    35 private: // NO_FUNCTION_TEMPLATE_ORDERING workaround
    36 
    37     template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
    38     std::string to_text_impl(
    39           const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) >& operand, long
    40         ) const
    41     {
    42         std::ostringstream ost;
    43         ost << "[V] " << boost::apply_visitor(to_text(), operand);
    44 
    45         return ost.str();
    46     }
    47 
    48     template <typename Value>
    49     std::string to_text_impl(const Value& operand, int) const
    50     {
    51         std::ostringstream ost;
    52         ost << "[V] " << operand;
    53 
    54         return ost.str();
    55     }
    56 
    57 public:
    58 
    59     template <typename T>
    60     std::string operator()(const T& operand) const
    61     {
    62         return to_text_impl(operand, 1L);
    63     }
    64 
    65 };
    66 
    67 struct total_sizeof : boost::static_visitor<int>
    68 {
    69    total_sizeof() : total_(0) { }
    70 
    71    template<class Value>
    72    int operator()(const Value&) const
    73    {
    74       total_ += sizeof(Value);
    75       return total_;
    76    }
    77 
    78    int result() const
    79    {
    80       return total_;
    81    }
    82 
    83    mutable int total_;
    84 
    85 }; // total_sizeof
    86 
    87 
    88 
    89 //Function object: sum_int
    90 //Description: Compute total sum of a series of numbers, (when called successively)
    91 //Use sizeof(T) if applied with a non-integral type
    92 struct sum_int : boost::static_visitor<int>
    93 {
    94    
    95    sum_int() : total_(0) { }
    96 
    97 
    98    template<int n>
    99    struct int_to_type
   100    {
   101       BOOST_STATIC_CONSTANT(int, value = n);
   102    }; 
   103 
   104    //Integral type - add numerical value
   105    template<typename T>
   106    void add(T t, int_to_type<true> ) const
   107    {
   108       total_ += t;
   109    }
   110 
   111    //Other types - add sizeof<T>
   112    template<typename T>
   113    void add(T& , int_to_type<false> ) const
   114    {
   115       total_ += sizeof(T);
   116    }
   117 
   118    template<typename T>
   119    int operator()(const T& t) const
   120    {
   121       //Int_to_type is used to select the correct add() overload
   122       add(t, int_to_type<boost::is_integral<T>::value>());
   123       return total_;
   124    }
   125 
   126    int result() const
   127    {
   128       return total_;
   129    }
   130 
   131 private:
   132    mutable int total_;
   133 
   134 }; //sum_int
   135 
   136 
   137 
   138 
   139 
   140 
   141 //Function object: sum_double
   142 //Description: Compute total sum of a series of numbers, (when called successively)
   143 //Accpetable input types: float, double (Other types are silently ignored)
   144 struct sum_double : boost::static_visitor<double>
   145 {
   146    
   147    sum_double() : total_(0) { }
   148 
   149    void operator()(float value) const
   150    {
   151       total_ += value;
   152    }
   153 
   154    void operator()(double value) const
   155    {
   156       total_ += value;
   157    }
   158 
   159    template<typename T>
   160    void operator()(const T&) const
   161    {
   162       //Do nothing
   163    }
   164 
   165    double result() const
   166    {
   167       return total_;
   168    }
   169 
   170 private:
   171    mutable double total_;
   172 
   173 }; //sum_double
   174 
   175 
   176 
   177 struct int_printer : boost::static_visitor<std::string>
   178 {
   179    
   180    int_printer(std::string prefix_s = "") : prefix_s_(prefix_s) { }
   181    int_printer(const int_printer& other) : prefix_s_(other.prefix_s_)
   182    {
   183       ost_ << other.str();
   184    }
   185 
   186    std::string operator()(int x) const
   187    {
   188       ost_ << prefix_s_ << x;
   189       return str();
   190    }
   191 
   192    std::string operator()(const std::vector<int>& x) const
   193    {
   194       ost_ << prefix_s_;
   195 
   196       //Use another Int_printer object for printing a list of all integers
   197       int_printer job(",");
   198       ost_ << std::for_each(x.begin(), x.end(), job).str();
   199       
   200       return str();
   201    }
   202 
   203    std::string str() const
   204    {
   205       return ost_.str();
   206    }
   207 
   208 private:
   209    std::string prefix_s_;
   210    mutable std::ostringstream ost_;
   211 };  //int_printer
   212 
   213 
   214 struct int_adder : boost::static_visitor<>
   215 {
   216    
   217    int_adder(int rhs) : rhs_(rhs) { }
   218 
   219    result_type operator()(int& lhs) const
   220    {
   221       lhs += rhs_;
   222    }
   223 
   224    template<typename T>
   225    result_type operator()(const T& ) const
   226    {
   227       //Do nothing
   228    }
   229 
   230    int rhs_;
   231 }; //int_adder
   232 
   233 
   234 
   235 
   236 struct held_type_name : boost::static_visitor<std::string>
   237 {
   238    
   239    template<typename T>
   240    std::string operator()(const T& ) const
   241    {
   242       ost_ << '[' << typeid(T).name() << ']';
   243       return result();
   244    }
   245 
   246    std::string result() const
   247    {
   248       return ost_.str();
   249    }
   250 
   251    mutable std::ostringstream ost_;
   252 
   253 }; //held_type_name
   254 
   255 
   256 
   257 
   258 template<typename T>
   259 struct spec 
   260 {
   261    typedef T result;
   262 };
   263 
   264 template<typename VariantType, typename S>
   265 inline void verify(VariantType& var, spec<S>, std::string str = "")
   266 {
   267    const VariantType& cvar = var;
   268 
   269    BOOST_CHECK(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
   270    BOOST_CHECK(cvar.type() == typeid(S));
   271 
   272    //
   273    // Check get<>()
   274    //
   275    BOOST_CHECK(boost::get<S>(&var));
   276    BOOST_CHECK(boost::get<S>(&cvar));
   277 
   278    const S* ptr1 = 0;
   279    const S* ptr2 = 0;
   280    try
   281    {
   282       S& r = boost::get<S>(var);
   283       ptr1 = &r;
   284    }
   285    catch(boost::bad_get& )
   286    {
   287       BOOST_ERROR( "get<S> failed unexpectedly" );
   288    }
   289 
   290    try
   291    {
   292       const S& cr = boost::get<S>(cvar);
   293       ptr2 = &cr;
   294    }
   295    catch(boost::bad_get& )
   296    {
   297       BOOST_ERROR( "get<S> const failed unexpectedly" );
   298    }
   299 
   300    BOOST_CHECK(ptr1 != 0 && ptr2 == ptr1);
   301 
   302    //
   303    // Check string content
   304    //
   305    if(str.length() > 0)
   306    {
   307       std::string temp = boost::apply_visitor(to_text(), cvar);
   308       std::cout << "temp = " << temp << ", str = " << str << std::endl;
   309       BOOST_CHECK(temp == str);         
   310    }
   311 }
   312 
   313 
   314 template<typename VariantType, typename S>
   315 inline void verify_not(VariantType& var, spec<S>)
   316 {
   317    const VariantType& cvar = var;
   318 
   319    BOOST_CHECK(cvar.type() != typeid(S));
   320 
   321    //
   322    // Check get<>()
   323    //
   324    BOOST_CHECK(!boost::get<S>(&var));
   325    BOOST_CHECK(!boost::get<S>(&cvar));
   326 
   327    const S* ptr1 = 0;
   328    const S* ptr2 = 0;
   329    try
   330    {
   331       S& r = boost::get<S>(var); // should throw
   332       BOOST_ERROR( "get<S> passed unexpectedly" );
   333 
   334       ptr1 = &r;
   335    }
   336    catch(boost::bad_get& )
   337    {
   338       // do nothing except pass-through
   339    }
   340 
   341    try
   342    {
   343       const S& cr = boost::get<S>(var); // should throw
   344       BOOST_ERROR( "get<S> const passed unexpectedly" );
   345 
   346       ptr2 = &cr;
   347    }
   348    catch(boost::bad_get& )
   349    {
   350       // do nothing except pass-through
   351    }
   352 
   353    BOOST_CHECK(ptr1 == 0 && ptr2 == 0);   
   354 }
   355 
   356 
   357 #endif //_JOBSH_INC_