• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   matches_relation_factory.hpp
9  * \author Andrey Semashev
10  * \date   03.08.2013
11  *
12  * \brief  This header is the Boost.Log library implementation, see the library documentation
13  *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14  */
15 
16 #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
17 
18 #include <boost/log/detail/setup_config.hpp>
19 
20 #if defined(BOOST_LOG_USE_STD_REGEX) && defined(BOOST_NO_CXX11_HDR_REGEX)
21 #error "Boost.Log: Cannot use std::regex because it is not supported by the standard library."
22 #endif
23 
24 #if !defined(BOOST_LOG_USE_BOOST_REGEX) && !defined(BOOST_LOG_USE_STD_REGEX) && !defined(BOOST_LOG_USE_BOOST_XPRESSIVE)
25 // Use Boost.Regex backend by default. It produces smaller executables and also has the best performance for small string matching.
26 // Note: This default has to be in sync with Boost.Log Jamfile.v2.
27 #define BOOST_LOG_USE_BOOST_REGEX
28 #endif
29 
30 #include <string>
31 #if defined(BOOST_LOG_USE_STD_REGEX)
32 #include <regex>
33 #include <boost/log/support/std_regex.hpp>
34 #elif defined(BOOST_LOG_USE_BOOST_REGEX)
35 #include <boost/regex.hpp>
36 #include <boost/log/support/regex.hpp>
37 #else
38 #include <boost/xpressive/xpressive_dynamic.hpp>
39 #include <boost/log/support/xpressive.hpp>
40 #endif
41 #include <boost/log/utility/string_literal.hpp>
42 #include <boost/log/utility/functional/matches.hpp>
43 #include <boost/log/utility/type_dispatch/standard_types.hpp>
44 #include <boost/log/detail/code_conversion.hpp>
45 #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T)
46 #include <boost/fusion/container/set.hpp>
47 #include <boost/fusion/sequence/intrinsic/at_key.hpp>
48 #include <boost/fusion/algorithm/iteration/for_each.hpp>
49 #endif
50 #include "default_filter_factory.hpp"
51 #include <boost/log/detail/header.hpp>
52 
53 namespace boost {
54 
55 BOOST_LOG_OPEN_NAMESPACE
56 
57 namespace aux {
58 
59 BOOST_LOG_ANONYMOUS_NAMESPACE {
60 
61 #if defined(BOOST_LOG_USE_STD_REGEX) || defined(BOOST_LOG_USE_BOOST_REGEX)
62 
63 #if defined(BOOST_LOG_USE_STD_REGEX)
64 namespace regex_namespace = std;
65 #else
66 namespace regex_namespace = boost;
67 #endif
68 
69 #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T)
70 
71 //! A special filtering predicate that adopts the string operand to the attribute value character type
72 struct matches_predicate :
73     public matches_fun
74 {
75     template< typename CharT >
76     struct initializer
77     {
78         typedef void result_type;
79         typedef CharT char_type;
80         typedef std::basic_string< char_type > string_type;
81 
82         explicit initializer(string_type const& val) : m_initializer(val)
83         {
84         }
85 
86         template< typename T >
87         result_type operator() (T& val) const
88         {
89             try
90             {
91                 typedef typename T::value_type target_char_type;
92                 std::basic_string< target_char_type > str;
93                 log::aux::code_convert(m_initializer, str);
94                 val.assign(str, T::ECMAScript | T::optimize);
95             }
96             catch (...)
97             {
98             }
99         }
100 
101     private:
102         string_type const& m_initializer;
103     };
104 
105     typedef matches_fun::result_type result_type;
106 
107     template< typename CharT >
108     explicit matches_predicate(std::basic_string< CharT > const& operand)
109     {
110         fusion::for_each(m_operands, initializer< CharT >(operand));
111     }
112 
113     template< typename T >
114     result_type operator() (T const& val) const
115     {
116         typedef typename T::value_type char_type;
117         typedef regex_namespace::basic_regex< char_type > regex_type;
118         return matches_fun::operator() (val, fusion::at_key< regex_type >(m_operands));
119     }
120 
121 private:
122     fusion::set< regex_namespace::regex, regex_namespace::wregex > m_operands;
123 };
124 
125 #else
126 
127 //! A special filtering predicate that adopts the string operand to the attribute value character type
128 template< typename CharT >
129 struct matches_predicate :
130     public matches_fun
131 {
132     typedef typename matches_fun::result_type result_type;
133     typedef CharT char_type;
134     typedef std::basic_string< char_type > string_type;
135     typedef regex_namespace::basic_regex< char_type > regex_type;
136 
137     explicit matches_predicate(string_type const& operand) :
138         m_operand(operand, regex_type::ECMAScript | regex_type::optimize)
139     {
140     }
141 
142     template< typename T >
143     result_type operator() (T const& val) const
144     {
145         return matches_fun::operator() (val, m_operand);
146     }
147 
148 private:
149     regex_type m_operand;
150 };
151 
152 #endif
153 
154 #else // defined(BOOST_LOG_USE_STD_REGEX) || defined(BOOST_LOG_USE_BOOST_REGEX)
155 
156 #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T)
157 
158 //! A special filtering predicate that adopts the string operand to the attribute value character type
159 struct matches_predicate :
160     public matches_fun
161 {
162     template< typename CharT >
163     struct initializer
164     {
165         typedef void result_type;
166         typedef CharT char_type;
167         typedef std::basic_string< char_type > string_type;
168 
169         explicit initializer(string_type const& val) : m_initializer(val)
170         {
171         }
172 
173         template< typename T >
174         result_type operator() (T& val) const
175         {
176             try
177             {
178                 typedef typename T::char_type target_char_type;
179                 std::basic_string< target_char_type > str;
180                 log::aux::code_convert(m_initializer, str);
181                 val = T::compile(str.c_str(), str.size(), T::ECMAScript | T::optimize);
182             }
183             catch (...)
184             {
185             }
186         }
187 
188     private:
189         string_type const& m_initializer;
190     };
191 
192     typedef matches_fun::result_type result_type;
193 
194     template< typename CharT >
195     explicit matches_predicate(std::basic_string< CharT > const& operand)
196     {
197         fusion::for_each(m_operands, initializer< CharT >(operand));
198     }
199 
200     template< typename T >
201     result_type operator() (T const& val) const
202     {
203         typedef typename T::value_type char_type;
204         typedef xpressive::basic_regex< const char_type* > regex_type;
205         return matches_fun::operator() (val, fusion::at_key< regex_type >(m_operands));
206     }
207 
208 private:
209     fusion::set< xpressive::cregex, xpressive::wcregex > m_operands;
210 };
211 
212 #else
213 
214 //! A special filtering predicate that adopts the string operand to the attribute value character type
215 template< typename CharT >
216 struct matches_predicate :
217     public matches_fun
218 {
219     typedef typename matches_fun::result_type result_type;
220     typedef CharT char_type;
221     typedef std::basic_string< char_type > string_type;
222     typedef xpressive::basic_regex< const char_type* > regex_type;
223 
224     explicit matches_predicate(string_type const& operand) :
225         m_operand(regex_type::compile(operand.c_str(), operand.size(), regex_type::ECMAScript | regex_type::optimize))
226     {
227     }
228 
229     template< typename T >
230     result_type operator() (T const& val) const
231     {
232         return matches_fun::operator() (val, m_operand);
233     }
234 
235 private:
236     regex_type m_operand;
237 };
238 
239 #endif
240 
241 #endif // defined(BOOST_LOG_USE_STD_REGEX) || defined(BOOST_LOG_USE_BOOST_REGEX)
242 
243 } // namespace
244 
245 //! The function parses the "matches" relation
246 template< typename CharT >
247 filter parse_matches_relation(attribute_name const& name, std::basic_string< CharT > const& operand)
248 {
249 #if defined(BOOST_LOG_USE_CHAR) && defined(BOOST_LOG_USE_WCHAR_T)
250     return predicate_wrapper< log::string_types::type, matches_predicate >(name, matches_predicate(operand));
251 #else
252     return predicate_wrapper< std::basic_string< CharT >, matches_predicate< CharT > >(name, matches_predicate< CharT >(operand));
253 #endif
254 }
255 
256 //  Explicitly instantiate factory implementation
257 #ifdef BOOST_LOG_USE_CHAR
258 template
259 filter parse_matches_relation< char >(attribute_name const& name, std::basic_string< char > const& operand);
260 #endif
261 #ifdef BOOST_LOG_USE_WCHAR_T
262 template
263 filter parse_matches_relation< wchar_t >(attribute_name const& name, std::basic_string< wchar_t > const& operand);
264 #endif
265 
266 } // namespace aux
267 
268 BOOST_LOG_CLOSE_NAMESPACE // namespace log
269 
270 } // namespace boost
271 
272 #include <boost/log/detail/footer.hpp>
273 
274 #endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
275