jobs.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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. #ifndef _JOBSH_INC_
  13. #define _JOBSH_INC_
  14. #include <algorithm>
  15. #include <iostream>
  16. #include <sstream>
  17. #include <string>
  18. #include <typeinfo>
  19. #include <vector>
  20. #include "boost/variant/variant_fwd.hpp"
  21. #include "boost/variant/get.hpp"
  22. #include "boost/variant/apply_visitor.hpp"
  23. #include "boost/variant/static_visitor.hpp"
  24. #include "boost/type_index.hpp"
  25. #include "boost/detail/workaround.hpp"
  26. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
  27. # pragma warn -lvc
  28. #endif
  29. struct to_text : boost::static_visitor<std::string>
  30. {
  31. private: // NO_FUNCTION_TEMPLATE_ORDERING workaround
  32. template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
  33. std::string to_text_impl(
  34. const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) >& operand, long
  35. ) const
  36. {
  37. std::ostringstream ost;
  38. ost << "[V] " << boost::apply_visitor(to_text(), operand);
  39. return ost.str();
  40. }
  41. template <typename Value>
  42. std::string to_text_impl(const Value& operand, int) const
  43. {
  44. std::ostringstream ost;
  45. ost << "[V] " << operand;
  46. return ost.str();
  47. }
  48. public:
  49. template <typename T>
  50. std::string operator()(const T& operand) const
  51. {
  52. return to_text_impl(operand, 1L);
  53. }
  54. };
  55. struct total_sizeof : boost::static_visitor<int>
  56. {
  57. total_sizeof() : total_(0) { }
  58. template<class Value>
  59. int operator()(const Value&) const
  60. {
  61. total_ += sizeof(Value);
  62. return total_;
  63. }
  64. int result() const
  65. {
  66. return total_;
  67. }
  68. mutable int total_;
  69. }; // total_sizeof
  70. //Function object: sum_int
  71. //Description: Compute total sum of a series of numbers, (when called successively)
  72. //Use sizeof(T) if applied with a non-integral type
  73. struct sum_int : boost::static_visitor<int>
  74. {
  75. sum_int() : total_(0) { }
  76. template<int n>
  77. struct int_to_type
  78. {
  79. BOOST_STATIC_CONSTANT(int, value = n);
  80. };
  81. //Integral type - add numerical value
  82. template<typename T>
  83. void add(T t, int_to_type<true> ) const
  84. {
  85. total_ += t;
  86. }
  87. //Other types - add sizeof<T>
  88. template<typename T>
  89. void add(T& , int_to_type<false> ) const
  90. {
  91. total_ += sizeof(T);
  92. }
  93. template<typename T>
  94. int operator()(const T& t) const
  95. {
  96. //Int_to_type is used to select the correct add() overload
  97. add(t, int_to_type<boost::is_integral<T>::value>());
  98. return total_;
  99. }
  100. int result() const
  101. {
  102. return total_;
  103. }
  104. private:
  105. mutable int total_;
  106. }; //sum_int
  107. //Function object: sum_double
  108. //Description: Compute total sum of a series of numbers, (when called successively)
  109. //Accpetable input types: float, double (Other types are silently ignored)
  110. struct sum_double : boost::static_visitor<double>
  111. {
  112. sum_double() : total_(0) { }
  113. void operator()(float value) const
  114. {
  115. total_ += value;
  116. }
  117. void operator()(double value) const
  118. {
  119. total_ += value;
  120. }
  121. template<typename T>
  122. void operator()(const T&) const
  123. {
  124. //Do nothing
  125. }
  126. double result() const
  127. {
  128. return total_;
  129. }
  130. private:
  131. mutable double total_;
  132. }; //sum_double
  133. struct int_printer : boost::static_visitor<std::string>
  134. {
  135. int_printer(std::string prefix_s = "") : prefix_s_(prefix_s) { }
  136. int_printer(const int_printer& other) : prefix_s_(other.prefix_s_)
  137. {
  138. ost_ << other.str();
  139. }
  140. std::string operator()(int x) const
  141. {
  142. ost_ << prefix_s_ << x;
  143. return str();
  144. }
  145. std::string operator()(const std::vector<int>& x) const
  146. {
  147. ost_ << prefix_s_;
  148. //Use another Int_printer object for printing a list of all integers
  149. int_printer job(",");
  150. ost_ << std::for_each(x.begin(), x.end(), job).str();
  151. return str();
  152. }
  153. std::string str() const
  154. {
  155. return ost_.str();
  156. }
  157. private:
  158. std::string prefix_s_;
  159. mutable std::ostringstream ost_;
  160. }; //int_printer
  161. struct int_adder : boost::static_visitor<>
  162. {
  163. int_adder(int rhs) : rhs_(rhs) { }
  164. result_type operator()(int& lhs) const
  165. {
  166. lhs += rhs_;
  167. }
  168. template<typename T>
  169. result_type operator()(const T& ) const
  170. {
  171. //Do nothing
  172. }
  173. int rhs_;
  174. }; //int_adder
  175. template<typename T>
  176. struct spec
  177. {
  178. typedef T result;
  179. };
  180. template<typename VariantType, typename S>
  181. inline void verify(VariantType& var, spec<S>, std::string str = "")
  182. {
  183. const VariantType& cvar = var;
  184. BOOST_TEST(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S));
  185. BOOST_TEST(cvar.type() == boost::typeindex::type_id<S>());
  186. //
  187. // Check get<>()
  188. //
  189. BOOST_TEST(boost::get<S>(&var));
  190. BOOST_TEST(boost::get<S>(&cvar));
  191. const S* ptr1 = 0;
  192. const S* ptr2 = 0;
  193. try
  194. {
  195. S& r = boost::get<S>(var);
  196. ptr1 = &r;
  197. }
  198. catch(const boost::bad_get& )
  199. {
  200. BOOST_ERROR( "get<S> failed unexpectedly" );
  201. }
  202. try
  203. {
  204. const S& cr = boost::get<S>(cvar);
  205. ptr2 = &cr;
  206. }
  207. catch(const boost::bad_get& )
  208. {
  209. BOOST_ERROR( "get<S> const failed unexpectedly" );
  210. }
  211. BOOST_TEST(ptr1 != 0 && ptr2 == ptr1);
  212. //
  213. // Check string content
  214. //
  215. if(str.length() > 0)
  216. {
  217. std::string temp = boost::apply_visitor(to_text(), cvar);
  218. std::cout << "temp = " << temp << ", str = " << str << std::endl;
  219. BOOST_TEST(temp == str);
  220. }
  221. }
  222. template<typename VariantType, typename S>
  223. inline void verify_not(VariantType& var, spec<S>)
  224. {
  225. const VariantType& cvar = var;
  226. BOOST_TEST(cvar.type() != boost::typeindex::type_id<S>());
  227. //
  228. // Check get<>()
  229. //
  230. BOOST_TEST(!boost::get<S>(&var));
  231. BOOST_TEST(!boost::get<S>(&cvar));
  232. const S* ptr1 = 0;
  233. const S* ptr2 = 0;
  234. try
  235. {
  236. S& r = boost::get<S>(var); // should throw
  237. BOOST_ERROR( "get<S> passed unexpectedly" );
  238. ptr1 = &r;
  239. }
  240. catch(const boost::bad_get& )
  241. {
  242. // do nothing except pass-through
  243. }
  244. try
  245. {
  246. const S& cr = boost::get<S>(var); // should throw
  247. BOOST_ERROR( "get<S> const passed unexpectedly" );
  248. ptr2 = &cr;
  249. }
  250. catch(const boost::bad_get& )
  251. {
  252. // do nothing except pass-through
  253. }
  254. BOOST_TEST(ptr1 == 0 && ptr2 == 0);
  255. }
  256. #endif //_JOBSH_INC_