callable.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Boost.Convert test and usage example
  2. // Copyright (c) 2009-2016 Vladimir Batov.
  3. // Use, modification and distribution are subject to the Boost Software License,
  4. // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
  5. #include "./test.hpp"
  6. #if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
  7. int main(int, char const* []) { return 0; }
  8. #else
  9. #include <boost/convert.hpp>
  10. #include <boost/convert/lexical_cast.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. #include <boost/function.hpp>
  13. #include <boost/bind.hpp>
  14. using std::string;
  15. using boost::convert;
  16. using boost::lexical_cast;
  17. //[callable_example1
  18. void plain_old_func(string const& value_in, boost::optional<int>& value_out)
  19. //]
  20. {
  21. try
  22. {
  23. value_out = lexical_cast<int>(value_in);
  24. }
  25. catch (...)
  26. {
  27. }
  28. }
  29. template<typename TypeIn, typename TypeOut>
  30. void
  31. convert_all(TypeIn const&, boost::optional<TypeOut>&)
  32. {
  33. }
  34. template<typename Type>
  35. void
  36. assign(boost::optional<Type>& value_out, Type const& value_in)
  37. {
  38. value_out = value_in;
  39. }
  40. struct converter1
  41. {
  42. template<typename TypeIn, typename TypeOut>
  43. void
  44. operator()(TypeIn const&, boost::optional<TypeOut>&) const
  45. {
  46. }
  47. };
  48. //[callable_example4
  49. struct take_double { void operator()(double, boost::optional<string>&) const {}};
  50. struct take_int { void operator()(int, boost::optional<string>&) const {}};
  51. //]
  52. //[callable_example6
  53. struct double_only
  54. {
  55. // Declared for all types.
  56. template<typename TypeIn> void operator()(TypeIn, boost::optional<string>&) const;
  57. };
  58. // Defined only for certain types.
  59. template<> void double_only::operator()<double>(double, boost::optional<string>&) const {}
  60. //]
  61. int
  62. main(int, char const* [])
  63. {
  64. typedef boost::function<void (string const& value_in, boost::optional<int>&)> boost_func;
  65. char const* const str = "-12";
  66. // Testing old-function-based converter.
  67. //[callable_example2
  68. int v01 = convert<int>(str, plain_old_func).value_or(-1);
  69. //]
  70. // Testing boost::function-based converter.
  71. int v02 = convert<int>(str, boost_func(plain_old_func)).value_or(-1);
  72. // Testing crazy boost::bind-based converter.
  73. //[callable_example3
  74. int v03 = convert<int>(str,
  75. boost::bind(assign<int>, _2,
  76. boost::bind(lexical_cast<int, string>, _1))).value_or(-1);
  77. //]
  78. BOOST_TEST(v01 == -12);
  79. BOOST_TEST(v02 == -12);
  80. BOOST_TEST(v03 == -12);
  81. convert<int>(str, convert_all<string, int>);
  82. convert<string>(11, convert_all<int, string>);
  83. convert< int>(str, converter1());
  84. convert<string>(11, converter1());
  85. convert<string>(11.23, take_double());
  86. convert<string>(11, take_int());
  87. //[callable_example5
  88. convert<string>(11, take_double()); // Compiler applies int-to-double promotion to call the converter.
  89. convert<string>(11.23, take_int()); // Compiler applies double-to-int implicit truncation.
  90. //]
  91. //[callable_example7
  92. convert<string>(11.23, double_only()); // Fine.
  93. // convert<string>(11, double_only()); // Fails: undefined reference to double_only::operator()<int>
  94. //]
  95. return boost::report_errors();
  96. }
  97. #endif