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   form_to_log_manip.cpp
9  * \author Andrey Semashev
10  * \date   05.07.2015
11  *
12  * \brief  This header contains tests for support for the \c to_log_manip customization point.
13  */
14 
15 #define BOOST_TEST_MODULE form_to_log_manip
16 
17 #include <string>
18 #include <ostream>
19 #include <algorithm>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/log/attributes/constant.hpp>
22 #include <boost/log/attributes/attribute_set.hpp>
23 #include <boost/log/utility/formatting_ostream.hpp>
24 #include <boost/log/utility/manipulators/to_log.hpp>
25 #include <boost/log/expressions.hpp>
26 #include <boost/log/core/record.hpp>
27 #include "char_definitions.hpp"
28 #include "make_record.hpp"
29 
30 namespace logging = boost::log;
31 namespace attrs = logging::attributes;
32 namespace expr = logging::expressions;
33 
34 namespace {
35 
36 struct my_class
37 {
38     int m_Data;
39 
my_class__anon1bec632b0111::my_class40     explicit my_class(int data) : m_Data(data) {}
41 };
42 
43 } // namespace
44 
45 BOOST_LOG_ATTRIBUTE_KEYWORD(a_my_class, "MyClass", my_class)
46 BOOST_LOG_ATTRIBUTE_KEYWORD(a_string, "String", std::string)
47 
48 namespace {
49 
50 template< typename CharT, typename TraitsT, typename AllocatorT >
51 inline logging::basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
operator <<(logging::basic_formatting_ostream<CharT,TraitsT,AllocatorT> & strm,logging::to_log_manip<my_class,tag::a_my_class> const & obj)52 operator<< (logging::basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, logging::to_log_manip< my_class, tag::a_my_class > const& obj)
53 {
54     strm << "a_my_class: [data: " << obj.get().m_Data << "]";
55     return strm;
56 }
57 
58 } // namespace
59 
60 namespace std {
61 
62 template< typename CharT, typename TraitsT, typename AllocatorT >
63 inline logging::basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
operator <<(logging::basic_formatting_ostream<CharT,TraitsT,AllocatorT> & strm,logging::to_log_manip<std::string,tag::a_string> const & obj)64 operator<< (logging::basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, logging::to_log_manip< std::string, tag::a_string > const& obj)
65 {
66     strm << "a_string: [" << obj.get() << "]";
67     return strm;
68 }
69 
70 } // namespace std
71 
BOOST_AUTO_TEST_CASE_TEMPLATE(operator_overrides,CharT,char_types)72 BOOST_AUTO_TEST_CASE_TEMPLATE(operator_overrides, CharT, char_types)
73 {
74     typedef logging::record_view record_view;
75     typedef logging::attribute_set attr_set;
76     typedef std::basic_string< CharT > string;
77     typedef logging::basic_formatting_ostream< CharT > osstream;
78     typedef logging::basic_formatter< CharT > formatter;
79 
80     attrs::constant< my_class > attr1(my_class(77));
81     attrs::constant< std::string > attr2("Hello");
82 
83     attr_set set1;
84     set1[a_my_class.get_name()] = attr1;
85     set1[a_string.get_name()] = attr2;
86 
87     record_view rec = make_record_view(set1);
88 
89     // Check that out custom operators are called
90     {
91         string str1, str2;
92         osstream strm1(str1), strm2(str2);
93         formatter f = expr::stream << a_my_class << ", " << a_string;
94         f(rec, strm1);
95         strm2 << "a_my_class: [data: " << 77 << "], a_string: [" << "Hello" << "]";
96         BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
97     }
98 }
99