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