File indexing completed on 2025-01-18 09:39:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
0016 #define BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
0017
0018 #include <vector>
0019 #include <string>
0020 #include <iterator>
0021 #include <boost/assert.hpp>
0022 #include <boost/mpl/bool.hpp>
0023 #include <boost/range/begin.hpp>
0024 #include <boost/range/end.hpp>
0025 #include <boost/range/size.hpp>
0026 #include <boost/range/const_iterator.hpp>
0027 #include <boost/range/value_type.hpp>
0028 #include <boost/move/core.hpp>
0029 #include <boost/move/utility_core.hpp>
0030 #include <boost/core/addressof.hpp>
0031 #include <boost/phoenix/core/actor.hpp>
0032 #include <boost/phoenix/core/meta_grammar.hpp>
0033 #include <boost/phoenix/core/terminal_fwd.hpp>
0034 #include <boost/phoenix/core/is_nullary.hpp>
0035 #include <boost/phoenix/core/environment.hpp>
0036 #include <boost/phoenix/support/vector.hpp>
0037 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
0038 #include <boost/type_traits/is_same.hpp>
0039 #include <boost/type_traits/remove_cv.hpp>
0040 #include <boost/type_traits/remove_reference.hpp>
0041 #include <boost/log/detail/config.hpp>
0042 #include <boost/log/detail/custom_terminal_spec.hpp>
0043 #include <boost/log/detail/deduce_char_type.hpp>
0044 #include <boost/log/detail/sfinae_tools.hpp>
0045 #include <boost/log/utility/formatting_ostream.hpp>
0046 #include <boost/log/detail/header.hpp>
0047
0048 #ifdef BOOST_HAS_PRAGMA_ONCE
0049 #pragma once
0050 #endif
0051
0052 namespace boost {
0053
0054 BOOST_LOG_OPEN_NAMESPACE
0055
0056 namespace expressions {
0057
0058 namespace aux {
0059
0060 template< typename RangeT >
0061 struct string_const_iterator : range_const_iterator< RangeT > {};
0062 template< >
0063 struct string_const_iterator< char* > { typedef char* type; };
0064 template< >
0065 struct string_const_iterator< const char* > { typedef const char* type; };
0066 template< >
0067 struct string_const_iterator< wchar_t* > { typedef wchar_t* type; };
0068 template< >
0069 struct string_const_iterator< const wchar_t* > { typedef const wchar_t* type; };
0070
0071 }
0072
0073
0074
0075
0076
0077 template< typename CharT >
0078 class pattern_replacer
0079 {
0080 public:
0081
0082 typedef void result_type;
0083
0084
0085 typedef CharT char_type;
0086
0087 typedef std::basic_string< char_type > string_type;
0088
0089 private:
0090
0091 struct string_lengths
0092 {
0093 unsigned int from_len, to_len;
0094 };
0095
0096
0097 typedef std::vector< string_lengths > string_lengths_list;
0098
0099 private:
0100
0101 string_type m_decoration_chars;
0102
0103 string_lengths_list m_string_lengths;
0104
0105 public:
0106
0107
0108
0109
0110
0111 template< typename RangeT >
0112 explicit pattern_replacer(RangeT const& decorations
0113 #ifndef BOOST_LOG_DOXYGEN_PASS
0114
0115 , typename boost::enable_if_has_type< typename range_const_iterator< RangeT >::type, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
0116 #endif
0117 )
0118 {
0119 typedef typename range_const_iterator< RangeT >::type iterator;
0120 for (iterator it = boost::begin(decorations), end_ = boost::end(decorations); it != end_; ++it)
0121 {
0122 string_lengths lens;
0123 {
0124 typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::first_type >::type first_iterator;
0125 first_iterator b = string_begin(it->first), e = string_end(it->first);
0126 lens.from_len = static_cast< unsigned int >(std::distance(b, e));
0127 m_decoration_chars.append(b, e);
0128 }
0129 {
0130 typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::second_type >::type second_iterator;
0131 second_iterator b = string_begin(it->second), e = string_end(it->second);
0132 lens.to_len = static_cast< unsigned int >(std::distance(b, e));
0133 m_decoration_chars.append(b, e);
0134 }
0135 m_string_lengths.push_back(lens);
0136 }
0137 }
0138
0139
0140
0141
0142
0143 template< typename FromRangeT, typename ToRangeT >
0144 pattern_replacer(FromRangeT const& from, ToRangeT const& to)
0145 {
0146 typedef typename range_const_iterator< FromRangeT >::type iterator1;
0147 typedef typename range_const_iterator< ToRangeT >::type iterator2;
0148 iterator1 it1 = boost::begin(from), end1 = boost::end(from);
0149 iterator2 it2 = boost::begin(to), end2 = boost::end(to);
0150 for (; it1 != end1 && it2 != end2; ++it1, ++it2)
0151 {
0152 string_lengths lens;
0153 {
0154 typedef typename aux::string_const_iterator< typename range_value< FromRangeT >::type >::type from_iterator;
0155 from_iterator b = string_begin(*it1), e = string_end(*it1);
0156 lens.from_len = static_cast< unsigned int >(std::distance(b, e));
0157 m_decoration_chars.append(b, e);
0158 }
0159 {
0160 typedef typename aux::string_const_iterator< typename range_value< ToRangeT >::type >::type to_iterator;
0161 to_iterator b = string_begin(*it2), e = string_end(*it2);
0162 lens.to_len = static_cast< unsigned int >(std::distance(b, e));
0163 m_decoration_chars.append(b, e);
0164 }
0165 m_string_lengths.push_back(lens);
0166 }
0167
0168
0169 BOOST_ASSERT(it1 == end1);
0170 BOOST_ASSERT(it2 == end2);
0171 }
0172
0173 pattern_replacer(pattern_replacer const& that) : m_decoration_chars(that.m_decoration_chars), m_string_lengths(that.m_string_lengths)
0174 {
0175 }
0176
0177
0178 result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
0179 {
0180 typedef typename string_type::size_type size_type;
0181
0182 const char_type* from_chars = m_decoration_chars.c_str();
0183 for (typename string_lengths_list::const_iterator it = m_string_lengths.begin(), end = m_string_lengths.end(); it != end; ++it)
0184 {
0185 const unsigned int from_len = it->from_len, to_len = it->to_len;
0186 const char_type* const to_chars = from_chars + from_len;
0187 for (size_type pos = str.find(from_chars, start_pos, from_len); pos != string_type::npos; pos = str.find(from_chars, pos, from_len))
0188 {
0189 str.replace(pos, from_len, to_chars, to_len);
0190 pos += to_len;
0191 }
0192 from_chars = to_chars + to_len;
0193 }
0194 }
0195
0196 private:
0197 static char_type* string_begin(char_type* p)
0198 {
0199 return p;
0200 }
0201 static const char_type* string_begin(const char_type* p)
0202 {
0203 return p;
0204 }
0205 template< typename RangeT >
0206 static typename range_const_iterator< RangeT >::type string_begin(RangeT const& r)
0207 {
0208 return boost::begin(r);
0209 }
0210
0211 static char_type* string_end(char_type* p)
0212 {
0213 return p + std::char_traits< char_type >::length(p);
0214 }
0215 static const char_type* string_end(const char_type* p)
0216 {
0217 return p + std::char_traits< char_type >::length(p);
0218 }
0219 template< typename RangeT >
0220 static typename range_const_iterator< RangeT >::type string_end(RangeT const& r)
0221 {
0222 return boost::end(r);
0223 }
0224 };
0225
0226 namespace aux {
0227
0228
0229 template< typename LeftT, typename SubactorT, typename ImplT >
0230 class char_decorator_output_terminal
0231 {
0232 private:
0233
0234 typedef char_decorator_output_terminal< LeftT, SubactorT, ImplT > this_type;
0235
0236 public:
0237 #ifndef BOOST_LOG_DOXYGEN_PASS
0238
0239 typedef void _is_boost_log_terminal;
0240 #endif
0241
0242
0243 typedef ImplT impl_type;
0244
0245
0246 typedef typename impl_type::char_type char_type;
0247
0248 typedef typename impl_type::string_type string_type;
0249
0250 typedef SubactorT subactor_type;
0251
0252
0253 template< typename >
0254 struct result;
0255
0256 template< typename ThisT, typename ContextT >
0257 struct result< ThisT(ContextT) >
0258 {
0259 typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
0260 typedef typename phoenix::evaluator::impl<
0261 typename LeftT::proto_base_expr&,
0262 context_type,
0263 phoenix::unused
0264 >::result_type type;
0265 };
0266
0267 private:
0268
0269 LeftT m_left;
0270
0271 subactor_type m_subactor;
0272
0273 impl_type m_impl;
0274
0275 public:
0276
0277
0278
0279 char_decorator_output_terminal(LeftT const& left, subactor_type const& sub, impl_type const& impl) :
0280 m_left(left), m_subactor(sub), m_impl(impl)
0281 {
0282 }
0283
0284
0285
0286 char_decorator_output_terminal(char_decorator_output_terminal const& that) :
0287 m_left(that.m_left), m_subactor(that.m_subactor), m_impl(that.m_impl)
0288 {
0289 }
0290
0291
0292
0293
0294 template< typename ContextT >
0295 typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
0296 {
0297
0298 typedef typename result< this_type(ContextT const&) >::type result_type;
0299 result_type strm = phoenix::eval(m_left, ctx);
0300 strm.flush();
0301 typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
0302
0303
0304 phoenix::eval(m_subactor, ctx);
0305
0306
0307 strm.flush();
0308 m_impl(*strm.rdbuf()->storage(), start_pos);
0309 strm.rdbuf()->ensure_max_size();
0310
0311 return strm;
0312 }
0313
0314
0315
0316
0317 template< typename ContextT >
0318 typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
0319 {
0320
0321 typedef typename result< const this_type(ContextT const&) >::type result_type;
0322 result_type strm = phoenix::eval(m_left, ctx);
0323 strm.flush();
0324 typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
0325
0326
0327 phoenix::eval(m_subactor, ctx);
0328
0329
0330 strm.flush();
0331 m_impl(*strm.rdbuf()->storage(), start_pos);
0332 strm.rdbuf()->ensure_max_size();
0333
0334 return strm;
0335 }
0336
0337 BOOST_DELETED_FUNCTION(char_decorator_output_terminal())
0338 };
0339
0340 }
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 template< typename SubactorT, typename ImplT >
0354 class char_decorator_terminal
0355 {
0356 private:
0357
0358 typedef char_decorator_terminal< SubactorT, ImplT > this_type;
0359
0360 public:
0361 #ifndef BOOST_LOG_DOXYGEN_PASS
0362
0363 typedef void _is_boost_log_terminal;
0364 #endif
0365
0366
0367 typedef ImplT impl_type;
0368
0369 typedef typename impl_type::char_type char_type;
0370
0371 typedef typename impl_type::string_type string_type;
0372
0373 typedef basic_formatting_ostream< char_type > stream_type;
0374
0375 typedef SubactorT subactor_type;
0376
0377
0378 typedef string_type result_type;
0379
0380 private:
0381
0382 subactor_type m_subactor;
0383
0384 impl_type m_impl;
0385
0386 public:
0387
0388
0389
0390 char_decorator_terminal(subactor_type const& sub, impl_type const& impl) : m_subactor(sub), m_impl(impl)
0391 {
0392 }
0393
0394
0395
0396 char_decorator_terminal(char_decorator_terminal const& that) : m_subactor(that.m_subactor), m_impl(that.m_impl)
0397 {
0398 }
0399
0400
0401
0402
0403 subactor_type const& get_subactor() const
0404 {
0405 return m_subactor;
0406 }
0407
0408
0409
0410
0411 impl_type const& get_impl() const
0412 {
0413 return m_impl;
0414 }
0415
0416
0417
0418
0419 template< typename ContextT >
0420 result_type operator() (ContextT const& ctx)
0421 {
0422 string_type str;
0423 stream_type strm(str);
0424
0425
0426 typedef phoenix::vector3<
0427 subactor_type*,
0428 typename fusion::result_of::at_c<
0429 typename remove_cv<
0430 typename remove_reference<
0431 typename phoenix::result_of::env< ContextT const& >::type
0432 >::type
0433 >::type::args_type,
0434 0
0435 >::type,
0436 stream_type&
0437 > env_type;
0438 env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
0439 phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
0440
0441
0442 strm.flush();
0443 m_impl(*strm.rdbuf()->storage());
0444
0445 return BOOST_LOG_NRVO_RESULT(str);
0446 }
0447
0448
0449
0450
0451 template< typename ContextT >
0452 result_type operator() (ContextT const& ctx) const
0453 {
0454 string_type str;
0455 stream_type strm(str);
0456
0457
0458 typedef phoenix::vector3<
0459 const subactor_type*,
0460 typename fusion::result_of::at_c<
0461 typename remove_cv<
0462 typename remove_reference<
0463 typename phoenix::result_of::env< ContextT const& >::type
0464 >::type
0465 >::type::args_type,
0466 0
0467 >::type,
0468 stream_type&
0469 > env_type;
0470 env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
0471 phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
0472
0473
0474 strm.flush();
0475 m_impl(*strm.rdbuf()->storage());
0476
0477 return BOOST_LOG_NRVO_RESULT(str);
0478 }
0479
0480 BOOST_DELETED_FUNCTION(char_decorator_terminal())
0481 };
0482
0483
0484
0485
0486 template< typename SubactorT, typename ImplT, template< typename > class ActorT = phoenix::actor >
0487 class char_decorator_actor :
0488 public ActorT< char_decorator_terminal< SubactorT, ImplT > >
0489 {
0490 public:
0491
0492 typedef char_decorator_terminal< SubactorT, ImplT > terminal_type;
0493
0494 typedef typename terminal_type::char_type char_type;
0495
0496
0497 typedef ActorT< terminal_type > base_type;
0498
0499 public:
0500
0501 explicit char_decorator_actor(base_type const& act) : base_type(act)
0502 {
0503 }
0504
0505
0506 terminal_type const& get_terminal() const
0507 {
0508 return this->proto_expr_.child0;
0509 }
0510 };
0511
0512 #ifndef BOOST_LOG_DOXYGEN_PASS
0513
0514 #define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
0515 template< typename LeftExprT, typename SubactorT, typename ImplT, template< typename > class ActorT >\
0516 BOOST_FORCEINLINE phoenix::actor< aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > >\
0517 operator<< (phoenix::actor< LeftExprT > left_ref left, char_decorator_actor< SubactorT, ImplT, ActorT > right_ref right)\
0518 {\
0519 typedef aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > terminal_type;\
0520 phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_terminal().get_subactor(), right.get_terminal().get_impl()) }};\
0521 return actor;\
0522 }
0523
0524 #include <boost/log/detail/generate_overloads.hpp>
0525
0526 #undef BOOST_LOG_AUX_OVERLOAD
0527
0528 #endif
0529
0530 namespace aux {
0531
0532 template< typename RangeT >
0533 class char_decorator_gen1
0534 {
0535 RangeT const& m_decorations;
0536
0537 typedef typename boost::log::aux::deduce_char_type< typename range_value< RangeT >::type::first_type >::type char_type;
0538
0539 public:
0540 explicit char_decorator_gen1(RangeT const& decorations) : m_decorations(decorations)
0541 {
0542 }
0543
0544 template< typename SubactorT >
0545 BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
0546 {
0547 typedef pattern_replacer< char_type > replacer_type;
0548 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
0549 typedef typename result_type::terminal_type terminal_type;
0550 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_decorations)) }};
0551 return result_type(act);
0552 }
0553 };
0554
0555 template< typename FromRangeT, typename ToRangeT >
0556 class char_decorator_gen2
0557 {
0558 FromRangeT const& m_from;
0559 ToRangeT const& m_to;
0560
0561 typedef typename boost::log::aux::deduce_char_type< typename range_value< FromRangeT >::type >::type from_char_type;
0562 typedef typename boost::log::aux::deduce_char_type< typename range_value< ToRangeT >::type >::type to_char_type;
0563 static_assert(is_same< from_char_type, to_char_type >::value, "Boost.Log: character decorator cannot be instantiated with different character types for source and replacement strings");
0564
0565 public:
0566 char_decorator_gen2(FromRangeT const& from, ToRangeT const& to) : m_from(from), m_to(to)
0567 {
0568 }
0569
0570 template< typename SubactorT >
0571 BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< from_char_type > > operator[] (SubactorT const& subactor) const
0572 {
0573 typedef pattern_replacer< from_char_type > replacer_type;
0574 typedef char_decorator_actor< SubactorT, replacer_type > result_type;
0575 typedef typename result_type::terminal_type terminal_type;
0576 typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_from, m_to)) }};
0577 return result_type(act);
0578 }
0579 };
0580
0581 }
0582
0583
0584
0585
0586
0587
0588
0589
0590 template< typename RangeT >
0591 BOOST_FORCEINLINE aux::char_decorator_gen1< RangeT > char_decor(RangeT const& decorations)
0592 {
0593 return aux::char_decorator_gen1< RangeT >(decorations);
0594 }
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 template< typename FromRangeT, typename ToRangeT >
0607 BOOST_FORCEINLINE aux::char_decorator_gen2< FromRangeT, ToRangeT > char_decor(FromRangeT const& from, ToRangeT const& to)
0608 {
0609 return aux::char_decorator_gen2< FromRangeT, ToRangeT >(from, to);
0610 }
0611
0612 }
0613
0614 BOOST_LOG_CLOSE_NAMESPACE
0615
0616 #ifndef BOOST_LOG_DOXYGEN_PASS
0617
0618 namespace phoenix {
0619
0620 namespace result_of {
0621
0622 template< typename SubactorT, typename ImplT >
0623 struct is_nullary< custom_terminal< boost::log::expressions::char_decorator_terminal< SubactorT, ImplT > > > :
0624 public mpl::false_
0625 {
0626 };
0627
0628 template< typename LeftT, typename SubactorT, typename ImplT >
0629 struct is_nullary< custom_terminal< boost::log::expressions::aux::char_decorator_output_terminal< LeftT, SubactorT, ImplT > > > :
0630 public mpl::false_
0631 {
0632 };
0633
0634 }
0635
0636 }
0637
0638 #endif
0639
0640 }
0641
0642 #include <boost/log/detail/footer.hpp>
0643
0644 #endif