attr_attribute_value_impl.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file attr_attribute_value_impl.cpp
  9. * \author Andrey Semashev
  10. * \date 25.01.2009
  11. *
  12. * \brief This header contains tests for the basic attribute value class.
  13. */
  14. #define BOOST_TEST_MODULE attr_attribute_value_impl
  15. #include <string>
  16. #include <boost/smart_ptr/intrusive_ptr.hpp>
  17. #include <boost/mpl/vector.hpp>
  18. #include <boost/test/unit_test.hpp>
  19. #include <boost/test/tools//floating_point_comparison.hpp>
  20. #include <boost/log/attributes/attribute_value.hpp>
  21. #include <boost/log/attributes/attribute_value_impl.hpp>
  22. #include <boost/log/attributes/value_extraction.hpp>
  23. #include <boost/log/attributes/value_visitation.hpp>
  24. #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
  25. #include <boost/log/utility/functional/bind_assign.hpp>
  26. namespace logging = boost::log;
  27. namespace attrs = logging::attributes;
  28. namespace {
  29. // Type dispatcher for the supported types
  30. struct my_dispatcher :
  31. public logging::static_type_dispatcher<
  32. boost::mpl::vector< int, double, std::string >
  33. >
  34. {
  35. typedef logging::static_type_dispatcher<
  36. boost::mpl::vector< int, double, std::string >
  37. > base_type;
  38. enum type_expected
  39. {
  40. none_expected,
  41. int_expected,
  42. double_expected,
  43. string_expected
  44. };
  45. my_dispatcher() :
  46. base_type(*this),
  47. m_Expected(none_expected),
  48. m_Int(0),
  49. m_Double(0.0)
  50. {
  51. }
  52. void set_expected()
  53. {
  54. m_Expected = none_expected;
  55. }
  56. void set_expected(int value)
  57. {
  58. m_Expected = int_expected;
  59. m_Int = value;
  60. }
  61. void set_expected(double value)
  62. {
  63. m_Expected = double_expected;
  64. m_Double = value;
  65. }
  66. void set_expected(std::string const& value)
  67. {
  68. m_Expected = string_expected;
  69. m_String = value;
  70. }
  71. // Implement visitation logic for all supported types
  72. void operator() (int const& value) const
  73. {
  74. BOOST_CHECK_EQUAL(m_Expected, int_expected);
  75. BOOST_CHECK_EQUAL(m_Int, value);
  76. }
  77. void operator() (double const& value) const
  78. {
  79. BOOST_CHECK_EQUAL(m_Expected, double_expected);
  80. BOOST_CHECK_CLOSE(m_Double, value, 0.001);
  81. }
  82. void operator() (std::string const& value) const
  83. {
  84. BOOST_CHECK_EQUAL(m_Expected, string_expected);
  85. BOOST_CHECK_EQUAL(m_String, value);
  86. }
  87. private:
  88. type_expected m_Expected;
  89. int m_Int;
  90. double m_Double;
  91. std::string m_String;
  92. };
  93. } // namespace
  94. // The test verifies that type dispatching works
  95. BOOST_AUTO_TEST_CASE(type_dispatching)
  96. {
  97. my_dispatcher disp;
  98. logging::attribute_value p1(attrs::make_attribute_value< int >(10));
  99. logging::attribute_value p2(attrs::make_attribute_value< double > (5.5));
  100. logging::attribute_value p3(attrs::make_attribute_value< std::string >(std::string("Hello, world!")));
  101. logging::attribute_value p4(attrs::make_attribute_value< float >(static_cast< float >(-7.2)));
  102. disp.set_expected(10);
  103. BOOST_CHECK(p1.dispatch(disp));
  104. BOOST_CHECK(p1.dispatch(disp)); // check that the contained value doesn't change over time or upon dispatching
  105. disp.set_expected(5.5);
  106. BOOST_CHECK(p2.dispatch(disp));
  107. disp.set_expected("Hello, world!");
  108. BOOST_CHECK(p3.dispatch(disp));
  109. disp.set_expected();
  110. BOOST_CHECK(!p4.dispatch(disp));
  111. }
  112. // The test verifies that value extraction works
  113. BOOST_AUTO_TEST_CASE(value_extraction)
  114. {
  115. logging::attribute_value p1(attrs::make_attribute_value< int >(10));
  116. logging::attribute_value p2(attrs::make_attribute_value< double >(5.5));
  117. logging::value_ref< int > val1 = p1.extract< int >();
  118. BOOST_CHECK(!!val1);
  119. BOOST_CHECK_EQUAL(val1.get(), 10);
  120. logging::value_ref< double > val2 = p1.extract< double >();
  121. BOOST_CHECK(!val2);
  122. double val3 = 0.0;
  123. BOOST_CHECK(p2.visit< double >(logging::bind_assign(val3)));
  124. BOOST_CHECK_CLOSE(val3, 5.5, 0.001);
  125. }
  126. // The test verifies that the detach_from_thread returns a valid pointer
  127. BOOST_AUTO_TEST_CASE(detaching_from_thread)
  128. {
  129. boost::intrusive_ptr< logging::attribute_value::impl > p1(new attrs::attribute_value_impl< int >(10));
  130. boost::intrusive_ptr< logging::attribute_value::impl > p2 = p1->detach_from_thread();
  131. BOOST_CHECK(!!p2);
  132. }