annotate DEPENDENCIES/generic/include/boost/xpressive/regex_algorithms.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file regex_algorithms.hpp
Chris@16 3 /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
Chris@16 4 //
Chris@16 5 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 6 // Software License, Version 1.0. (See accompanying file
Chris@16 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #ifndef BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
Chris@16 10 #define BOOST_XPRESSIVE_ALGORITHMS_HPP_EAN_10_04_2005
Chris@16 11
Chris@16 12 // MS compatible compilers support #pragma once
Chris@101 13 #if defined(_MSC_VER)
Chris@16 14 # pragma once
Chris@16 15 #endif
Chris@16 16
Chris@16 17 #include <string>
Chris@16 18 #include <iterator>
Chris@16 19 #include <boost/mpl/or.hpp>
Chris@16 20 #include <boost/range/end.hpp>
Chris@16 21 #include <boost/range/begin.hpp>
Chris@16 22 #include <boost/mpl/identity.hpp>
Chris@16 23 #include <boost/utility/enable_if.hpp>
Chris@16 24 #include <boost/type_traits/add_const.hpp>
Chris@16 25 #include <boost/type_traits/is_pointer.hpp>
Chris@16 26 #include <boost/type_traits/remove_const.hpp>
Chris@16 27 #include <boost/xpressive/match_results.hpp>
Chris@16 28 #include <boost/xpressive/detail/detail_fwd.hpp>
Chris@16 29 #include <boost/xpressive/detail/core/state.hpp>
Chris@16 30 #include <boost/xpressive/detail/utility/save_restore.hpp>
Chris@16 31
Chris@16 32 /// INTERNAL ONLY
Chris@16 33 ///
Chris@16 34 #define BOOST_XPR_NONDEDUCED_TYPE_(x) typename mpl::identity<x>::type
Chris@16 35
Chris@16 36 namespace boost { namespace xpressive
Chris@16 37 {
Chris@16 38
Chris@16 39 ///////////////////////////////////////////////////////////////////////////////
Chris@16 40 // regex_match
Chris@16 41 ///////////////////////////////////////////////////////////////////////////////
Chris@16 42
Chris@16 43 namespace detail
Chris@16 44 {
Chris@16 45 ///////////////////////////////////////////////////////////////////////////////
Chris@16 46 // regex_match_impl
Chris@16 47 template<typename BidiIter>
Chris@16 48 inline bool regex_match_impl
Chris@16 49 (
Chris@16 50 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 51 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 52 , match_results<BidiIter> &what
Chris@16 53 , basic_regex<BidiIter> const &re
Chris@16 54 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 55 )
Chris@16 56 {
Chris@16 57 typedef detail::core_access<BidiIter> access;
Chris@16 58 BOOST_ASSERT(0 != re.regex_id());
Chris@16 59
Chris@16 60 // the state object holds matching state and
Chris@16 61 // is passed by reference to all the matchers
Chris@16 62 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 63 state.flags_.match_all_ = true;
Chris@16 64 state.sub_match(0).begin_ = begin;
Chris@16 65
Chris@16 66 if(access::match(re, state))
Chris@16 67 {
Chris@16 68 access::set_prefix_suffix(what, begin, end);
Chris@16 69 return true;
Chris@16 70 }
Chris@16 71
Chris@16 72 // handle partial matches
Chris@16 73 else if(state.found_partial_match_ && 0 != (flags & regex_constants::match_partial))
Chris@16 74 {
Chris@16 75 state.set_partial_match();
Chris@16 76 return true;
Chris@16 77 }
Chris@16 78
Chris@16 79 access::reset(what);
Chris@16 80 return false;
Chris@16 81 }
Chris@16 82 } // namespace detail
Chris@16 83
Chris@16 84 /// \brief See if a regex matches a sequence from beginning to end.
Chris@16 85 ///
Chris@16 86 /// Determines whether there is an exact match between the regular expression \c re,
Chris@16 87 /// and all of the sequence <tt>[begin, end)</tt>.
Chris@16 88 ///
Chris@16 89 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
Chris@16 90 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
Chris@16 91 /// \param begin The beginning of the sequence.
Chris@16 92 /// \param end The end of the sequence.
Chris@16 93 /// \param what The \c match_results struct into which the sub_matches will be written
Chris@16 94 /// \param re The regular expression object to use
Chris@16 95 /// \param flags Optional match flags, used to control how the expression is matched
Chris@16 96 /// against the sequence. (See \c match_flag_type.)
Chris@16 97 /// \return \c true if a match is found, \c false otherwise
Chris@16 98 /// \throw regex_error on stack exhaustion
Chris@16 99 template<typename BidiIter>
Chris@16 100 inline bool regex_match
Chris@16 101 (
Chris@16 102 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 103 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 104 , match_results<BidiIter> &what
Chris@16 105 , basic_regex<BidiIter> const &re
Chris@16 106 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 107 )
Chris@16 108 {
Chris@16 109 typedef detail::core_access<BidiIter> access;
Chris@16 110
Chris@16 111 if(0 == re.regex_id())
Chris@16 112 {
Chris@16 113 access::reset(what);
Chris@16 114 return false;
Chris@16 115 }
Chris@16 116
Chris@16 117 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 118 }
Chris@16 119
Chris@16 120 /// \overload
Chris@16 121 ///
Chris@16 122 template<typename BidiIter>
Chris@16 123 inline bool regex_match
Chris@16 124 (
Chris@16 125 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 126 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 127 , basic_regex<BidiIter> const &re
Chris@16 128 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 129 )
Chris@16 130 {
Chris@16 131 if(0 == re.regex_id())
Chris@16 132 {
Chris@16 133 return false;
Chris@16 134 }
Chris@16 135
Chris@16 136 // BUGBUG this is inefficient
Chris@16 137 match_results<BidiIter> what;
Chris@16 138 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 139 }
Chris@16 140
Chris@16 141 /// \overload
Chris@16 142 ///
Chris@16 143 template<typename Char>
Chris@16 144 inline bool regex_match
Chris@16 145 (
Chris@16 146 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
Chris@16 147 , match_results<Char *> &what
Chris@16 148 , basic_regex<Char *> const &re
Chris@16 149 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 150 )
Chris@16 151 {
Chris@16 152 typedef detail::core_access<Char *> access;
Chris@16 153
Chris@16 154 if(0 == re.regex_id())
Chris@16 155 {
Chris@16 156 access::reset(what);
Chris@16 157 return false;
Chris@16 158 }
Chris@16 159
Chris@16 160 // BUGBUG this is inefficient
Chris@16 161 typedef typename remove_const<Char>::type char_type;
Chris@16 162 Char *end = begin + std::char_traits<char_type>::length(begin);
Chris@16 163 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 164 }
Chris@16 165
Chris@16 166 /// \overload
Chris@16 167 ///
Chris@16 168 template<typename BidiRange, typename BidiIter>
Chris@16 169 inline bool regex_match
Chris@16 170 (
Chris@16 171 BidiRange &rng
Chris@16 172 , match_results<BidiIter> &what
Chris@16 173 , basic_regex<BidiIter> const &re
Chris@16 174 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 175 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 176 )
Chris@16 177 {
Chris@16 178 typedef detail::core_access<BidiIter> access;
Chris@16 179
Chris@16 180 if(0 == re.regex_id())
Chris@16 181 {
Chris@16 182 access::reset(what);
Chris@16 183 return false;
Chris@16 184 }
Chris@16 185
Chris@16 186 // Note that the result iterator of the range must be convertible
Chris@16 187 // to BidiIter here.
Chris@16 188 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 189 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 190 }
Chris@16 191
Chris@16 192 /// \overload
Chris@16 193 ///
Chris@16 194 template<typename BidiRange, typename BidiIter>
Chris@16 195 inline bool regex_match
Chris@16 196 (
Chris@16 197 BidiRange const &rng
Chris@16 198 , match_results<BidiIter> &what
Chris@16 199 , basic_regex<BidiIter> const &re
Chris@16 200 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 201 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 202 )
Chris@16 203 {
Chris@16 204 typedef detail::core_access<BidiIter> access;
Chris@16 205
Chris@16 206 if(0 == re.regex_id())
Chris@16 207 {
Chris@16 208 access::reset(what);
Chris@16 209 return false;
Chris@16 210 }
Chris@16 211
Chris@16 212 // Note that the result iterator of the range must be convertible
Chris@16 213 // to BidiIter here.
Chris@16 214 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 215 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 216 }
Chris@16 217
Chris@16 218 /// \overload
Chris@16 219 ///
Chris@16 220 template<typename Char>
Chris@16 221 inline bool regex_match
Chris@16 222 (
Chris@16 223 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
Chris@16 224 , basic_regex<Char *> const &re
Chris@16 225 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 226 )
Chris@16 227 {
Chris@16 228 if(0 == re.regex_id())
Chris@16 229 {
Chris@16 230 return false;
Chris@16 231 }
Chris@16 232
Chris@16 233 // BUGBUG this is inefficient
Chris@16 234 match_results<Char *> what;
Chris@16 235 typedef typename remove_const<Char>::type char_type;
Chris@16 236 Char *end = begin + std::char_traits<char_type>::length(begin);
Chris@16 237 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 238 }
Chris@16 239
Chris@16 240 /// \overload
Chris@16 241 ///
Chris@16 242 template<typename BidiRange, typename BidiIter>
Chris@16 243 inline bool regex_match
Chris@16 244 (
Chris@16 245 BidiRange &rng
Chris@16 246 , basic_regex<BidiIter> const &re
Chris@16 247 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 248 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 249 )
Chris@16 250 {
Chris@16 251 if(0 == re.regex_id())
Chris@16 252 {
Chris@16 253 return false;
Chris@16 254 }
Chris@16 255
Chris@16 256 // BUGBUG this is inefficient
Chris@16 257 match_results<BidiIter> what;
Chris@16 258 // Note that the result iterator of the range must be convertible
Chris@16 259 // to BidiIter here.
Chris@16 260 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 261 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 262 }
Chris@16 263
Chris@16 264 /// \overload
Chris@16 265 ///
Chris@16 266 template<typename BidiRange, typename BidiIter>
Chris@16 267 inline bool regex_match
Chris@16 268 (
Chris@16 269 BidiRange const &rng
Chris@16 270 , basic_regex<BidiIter> const &re
Chris@16 271 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 272 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 273 )
Chris@16 274 {
Chris@16 275 if(0 == re.regex_id())
Chris@16 276 {
Chris@16 277 return false;
Chris@16 278 }
Chris@16 279
Chris@16 280 // BUGBUG this is inefficient
Chris@16 281 match_results<BidiIter> what;
Chris@16 282 // Note that the result iterator of the range must be convertible
Chris@16 283 // to BidiIter here.
Chris@16 284 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 285 return detail::regex_match_impl(begin, end, what, re, flags);
Chris@16 286 }
Chris@16 287
Chris@16 288
Chris@16 289 ///////////////////////////////////////////////////////////////////////////////
Chris@16 290 // regex_search
Chris@16 291 ///////////////////////////////////////////////////////////////////////////////
Chris@16 292
Chris@16 293 namespace detail
Chris@16 294 {
Chris@16 295 ///////////////////////////////////////////////////////////////////////////////
Chris@16 296 // regex_search_impl
Chris@16 297 template<typename BidiIter>
Chris@16 298 inline bool regex_search_impl
Chris@16 299 (
Chris@16 300 match_state<BidiIter> &state
Chris@16 301 , basic_regex<BidiIter> const &re
Chris@16 302 , bool not_initial_null = false
Chris@16 303 )
Chris@16 304 {
Chris@16 305 typedef core_access<BidiIter> access;
Chris@16 306 match_results<BidiIter> &what = *state.context_.results_ptr_;
Chris@16 307 BOOST_ASSERT(0 != re.regex_id());
Chris@16 308
Chris@16 309 bool const partial_ok = state.flags_.match_partial_;
Chris@16 310 save_restore<bool> not_null(state.flags_.match_not_null_, state.flags_.match_not_null_ || not_initial_null);
Chris@16 311 state.flags_.match_prev_avail_ = state.flags_.match_prev_avail_ || !state.bos();
Chris@16 312
Chris@16 313 regex_impl<BidiIter> const &impl = *access::get_regex_impl(re);
Chris@16 314 BidiIter const begin = state.cur_, end = state.end_;
Chris@16 315 BidiIter &sub0begin = state.sub_match(0).begin_;
Chris@16 316 sub0begin = state.cur_;
Chris@16 317
Chris@16 318 // If match_continuous is set, we only need to check for a match at the current position
Chris@16 319 if(state.flags_.match_continuous_)
Chris@16 320 {
Chris@16 321 if(access::match(re, state))
Chris@16 322 {
Chris@16 323 access::set_prefix_suffix(what, begin, end);
Chris@16 324 return true;
Chris@16 325 }
Chris@16 326
Chris@16 327 // handle partial matches
Chris@16 328 else if(partial_ok && state.found_partial_match_)
Chris@16 329 {
Chris@16 330 state.set_partial_match();
Chris@16 331 return true;
Chris@16 332 }
Chris@16 333 }
Chris@16 334
Chris@16 335 // If we have a finder, use it to find where a potential match can start
Chris@16 336 else if(impl.finder_ && (!partial_ok || impl.finder_->ok_for_partial_matches()))
Chris@16 337 {
Chris@16 338 finder<BidiIter> const &find = *impl.finder_;
Chris@16 339 if(find(state))
Chris@16 340 {
Chris@16 341 if(state.cur_ != begin)
Chris@16 342 {
Chris@16 343 not_null.restore();
Chris@16 344 }
Chris@16 345
Chris@16 346 do
Chris@16 347 {
Chris@16 348 sub0begin = state.cur_;
Chris@16 349 if(access::match(re, state))
Chris@16 350 {
Chris@16 351 access::set_prefix_suffix(what, begin, end);
Chris@16 352 return true;
Chris@16 353 }
Chris@16 354
Chris@16 355 // handle partial matches
Chris@16 356 else if(partial_ok && state.found_partial_match_)
Chris@16 357 {
Chris@16 358 state.set_partial_match();
Chris@16 359 return true;
Chris@16 360 }
Chris@16 361
Chris@16 362 BOOST_ASSERT(state.cur_ == sub0begin);
Chris@16 363 not_null.restore();
Chris@16 364 }
Chris@16 365 while(state.cur_ != state.end_ && (++state.cur_, find(state)));
Chris@16 366 }
Chris@16 367 }
Chris@16 368
Chris@16 369 // Otherwise, use brute force search at every position.
Chris@16 370 else
Chris@16 371 {
Chris@16 372 for(;;)
Chris@16 373 {
Chris@16 374 if(access::match(re, state))
Chris@16 375 {
Chris@16 376 access::set_prefix_suffix(what, begin, end);
Chris@16 377 return true;
Chris@16 378 }
Chris@16 379
Chris@16 380 // handle partial matches
Chris@16 381 else if(partial_ok && state.found_partial_match_)
Chris@16 382 {
Chris@16 383 state.set_partial_match();
Chris@16 384 return true;
Chris@16 385 }
Chris@16 386
Chris@16 387 else if(end == sub0begin)
Chris@16 388 {
Chris@16 389 break;
Chris@16 390 }
Chris@16 391
Chris@16 392 BOOST_ASSERT(state.cur_ == sub0begin);
Chris@16 393 state.cur_ = ++sub0begin;
Chris@16 394 not_null.restore();
Chris@16 395 }
Chris@16 396 }
Chris@16 397
Chris@16 398 access::reset(what);
Chris@16 399 return false;
Chris@16 400 }
Chris@16 401 } // namespace detail
Chris@16 402
Chris@16 403
Chris@16 404 /// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
Chris@16 405 /// that matches the regular expression \c re.
Chris@16 406 ///
Chris@16 407 /// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
Chris@16 408 /// the regular expression \c re.
Chris@16 409 ///
Chris@16 410 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
Chris@16 411 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
Chris@16 412 /// \param begin The beginning of the sequence
Chris@16 413 /// \param end The end of the sequence
Chris@16 414 /// \param what The \c match_results struct into which the sub_matches will be written
Chris@16 415 /// \param re The regular expression object to use
Chris@16 416 /// \param flags Optional match flags, used to control how the expression is matched against
Chris@16 417 /// the sequence. (See \c match_flag_type.)
Chris@16 418 /// \return \c true if a match is found, \c false otherwise
Chris@16 419 /// \throw regex_error on stack exhaustion
Chris@16 420 template<typename BidiIter>
Chris@16 421 inline bool regex_search
Chris@16 422 (
Chris@16 423 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 424 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 425 , match_results<BidiIter> &what
Chris@16 426 , basic_regex<BidiIter> const &re
Chris@16 427 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 428 )
Chris@16 429 {
Chris@16 430 typedef detail::core_access<BidiIter> access;
Chris@16 431
Chris@16 432 // a default-constructed regex matches nothing
Chris@16 433 if(0 == re.regex_id())
Chris@16 434 {
Chris@16 435 access::reset(what);
Chris@16 436 return false;
Chris@16 437 }
Chris@16 438
Chris@16 439 // the state object holds matching state and
Chris@16 440 // is passed by reference to all the matchers
Chris@16 441 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 442 return detail::regex_search_impl(state, re);
Chris@16 443 }
Chris@16 444
Chris@16 445 /// \overload
Chris@16 446 ///
Chris@16 447 template<typename BidiIter>
Chris@16 448 inline bool regex_search
Chris@16 449 (
Chris@16 450 BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 451 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 452 , basic_regex<BidiIter> const &re
Chris@16 453 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 454 )
Chris@16 455 {
Chris@16 456 typedef detail::core_access<BidiIter> access;
Chris@16 457
Chris@16 458 // a default-constructed regex matches nothing
Chris@16 459 if(0 == re.regex_id())
Chris@16 460 {
Chris@16 461 return false;
Chris@16 462 }
Chris@16 463
Chris@16 464 // BUGBUG this is inefficient
Chris@16 465 match_results<BidiIter> what;
Chris@16 466 // the state object holds matching state and
Chris@16 467 // is passed by reference to all the matchers
Chris@16 468 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 469 return detail::regex_search_impl(state, re);
Chris@16 470 }
Chris@16 471
Chris@16 472 /// \overload
Chris@16 473 ///
Chris@16 474 template<typename Char>
Chris@16 475 inline bool regex_search
Chris@16 476 (
Chris@16 477 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
Chris@16 478 , match_results<Char *> &what
Chris@16 479 , basic_regex<Char *> const &re
Chris@16 480 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 481 )
Chris@16 482 {
Chris@16 483 typedef detail::core_access<Char *> access;
Chris@16 484
Chris@16 485 // a default-constructed regex matches nothing
Chris@16 486 if(0 == re.regex_id())
Chris@16 487 {
Chris@16 488 access::reset(what);
Chris@16 489 return false;
Chris@16 490 }
Chris@16 491
Chris@16 492 // BUGBUG this is inefficient
Chris@16 493 typedef typename remove_const<Char>::type char_type;
Chris@16 494 Char *end = begin + std::char_traits<char_type>::length(begin);
Chris@16 495 // the state object holds matching state and
Chris@16 496 // is passed by reference to all the matchers
Chris@16 497 detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 498 return detail::regex_search_impl(state, re);
Chris@16 499 }
Chris@16 500
Chris@16 501 /// \overload
Chris@16 502 ///
Chris@16 503 template<typename BidiRange, typename BidiIter>
Chris@16 504 inline bool regex_search
Chris@16 505 (
Chris@16 506 BidiRange &rng
Chris@16 507 , match_results<BidiIter> &what
Chris@16 508 , basic_regex<BidiIter> const &re
Chris@16 509 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 510 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 511 )
Chris@16 512 {
Chris@16 513 typedef detail::core_access<BidiIter> access;
Chris@16 514
Chris@16 515 // a default-constructed regex matches nothing
Chris@16 516 if(0 == re.regex_id())
Chris@16 517 {
Chris@16 518 access::reset(what);
Chris@16 519 return false;
Chris@16 520 }
Chris@16 521
Chris@16 522 // Note that the result iterator of the range must be convertible
Chris@16 523 // to BidiIter here.
Chris@16 524 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 525 // the state object holds matching state and
Chris@16 526 // is passed by reference to all the matchers
Chris@16 527 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 528 return detail::regex_search_impl(state, re);
Chris@16 529 }
Chris@16 530
Chris@16 531 /// \overload
Chris@16 532 ///
Chris@16 533 template<typename BidiRange, typename BidiIter>
Chris@16 534 inline bool regex_search
Chris@16 535 (
Chris@16 536 BidiRange const &rng
Chris@16 537 , match_results<BidiIter> &what
Chris@16 538 , basic_regex<BidiIter> const &re
Chris@16 539 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 540 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 541 )
Chris@16 542 {
Chris@16 543 typedef detail::core_access<BidiIter> access;
Chris@16 544
Chris@16 545 // a default-constructed regex matches nothing
Chris@16 546 if(0 == re.regex_id())
Chris@16 547 {
Chris@16 548 access::reset(what);
Chris@16 549 return false;
Chris@16 550 }
Chris@16 551
Chris@16 552 // Note that the result iterator of the range must be convertible
Chris@16 553 // to BidiIter here.
Chris@16 554 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 555 // the state object holds matching state and
Chris@16 556 // is passed by reference to all the matchers
Chris@16 557 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 558 return detail::regex_search_impl(state, re);
Chris@16 559 }
Chris@16 560
Chris@16 561 /// \overload
Chris@16 562 ///
Chris@16 563 template<typename Char>
Chris@16 564 inline bool regex_search
Chris@16 565 (
Chris@16 566 BOOST_XPR_NONDEDUCED_TYPE_(Char) *begin
Chris@16 567 , basic_regex<Char *> const &re
Chris@16 568 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 569 )
Chris@16 570 {
Chris@16 571 typedef detail::core_access<Char *> access;
Chris@16 572
Chris@16 573 // a default-constructed regex matches nothing
Chris@16 574 if(0 == re.regex_id())
Chris@16 575 {
Chris@16 576 return false;
Chris@16 577 }
Chris@16 578
Chris@16 579 // BUGBUG this is inefficient
Chris@16 580 match_results<Char *> what;
Chris@16 581 // BUGBUG this is inefficient
Chris@16 582 typedef typename remove_const<Char>::type char_type;
Chris@16 583 Char *end = begin + std::char_traits<char_type>::length(begin);
Chris@16 584 // the state object holds matching state and
Chris@16 585 // is passed by reference to all the matchers
Chris@16 586 detail::match_state<Char *> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 587 return detail::regex_search_impl(state, re);
Chris@16 588 }
Chris@16 589
Chris@16 590 /// \overload
Chris@16 591 ///
Chris@16 592 template<typename BidiRange, typename BidiIter>
Chris@16 593 inline bool regex_search
Chris@16 594 (
Chris@16 595 BidiRange &rng
Chris@16 596 , basic_regex<BidiIter> const &re
Chris@16 597 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 598 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 599 )
Chris@16 600 {
Chris@16 601 typedef detail::core_access<BidiIter> access;
Chris@16 602
Chris@16 603 // a default-constructed regex matches nothing
Chris@16 604 if(0 == re.regex_id())
Chris@16 605 {
Chris@16 606 return false;
Chris@16 607 }
Chris@16 608
Chris@16 609 // BUGBUG this is inefficient
Chris@16 610 match_results<BidiIter> what;
Chris@16 611 // Note that the result iterator of the range must be convertible
Chris@16 612 // to BidiIter here.
Chris@16 613 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 614 // the state object holds matching state and
Chris@16 615 // is passed by reference to all the matchers
Chris@16 616 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 617 return detail::regex_search_impl(state, re);
Chris@16 618 }
Chris@16 619
Chris@16 620 /// \overload
Chris@16 621 ///
Chris@16 622 template<typename BidiRange, typename BidiIter>
Chris@16 623 inline bool regex_search
Chris@16 624 (
Chris@16 625 BidiRange const &rng
Chris@16 626 , basic_regex<BidiIter> const &re
Chris@16 627 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 628 , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
Chris@16 629 )
Chris@16 630 {
Chris@16 631 typedef detail::core_access<BidiIter> access;
Chris@16 632
Chris@16 633 // a default-constructed regex matches nothing
Chris@16 634 if(0 == re.regex_id())
Chris@16 635 {
Chris@16 636 return false;
Chris@16 637 }
Chris@16 638
Chris@16 639 // BUGBUG this is inefficient
Chris@16 640 match_results<BidiIter> what;
Chris@16 641 // Note that the result iterator of the range must be convertible
Chris@16 642 // to BidiIter here.
Chris@16 643 BidiIter begin = boost::begin(rng), end = boost::end(rng);
Chris@16 644 // the state object holds matching state and
Chris@16 645 // is passed by reference to all the matchers
Chris@16 646 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 647 return detail::regex_search_impl(state, re);
Chris@16 648 }
Chris@16 649
Chris@16 650
Chris@16 651 ///////////////////////////////////////////////////////////////////////////////
Chris@16 652 // regex_replace
Chris@16 653 ///////////////////////////////////////////////////////////////////////////////
Chris@16 654
Chris@16 655 namespace detail
Chris@16 656 {
Chris@16 657 ///////////////////////////////////////////////////////////////////////////////
Chris@16 658 // regex_replace_impl
Chris@16 659 template<typename OutIter, typename BidiIter, typename Formatter>
Chris@16 660 inline OutIter regex_replace_impl
Chris@16 661 (
Chris@16 662 OutIter out
Chris@16 663 , BidiIter begin
Chris@16 664 , BidiIter end
Chris@16 665 , basic_regex<BidiIter> const &re
Chris@16 666 , Formatter const &format
Chris@16 667 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 668 )
Chris@16 669 {
Chris@16 670 using namespace regex_constants;
Chris@16 671 typedef detail::core_access<BidiIter> access;
Chris@16 672 BOOST_ASSERT(0 != re.regex_id());
Chris@16 673
Chris@16 674 BidiIter cur = begin;
Chris@16 675 match_results<BidiIter> what;
Chris@16 676 detail::match_state<BidiIter> state(begin, end, what, *access::get_regex_impl(re), flags);
Chris@16 677 bool const yes_copy = (0 == (flags & format_no_copy));
Chris@16 678
Chris@16 679 if(detail::regex_search_impl(state, re))
Chris@16 680 {
Chris@16 681 if(yes_copy)
Chris@16 682 {
Chris@16 683 out = std::copy(cur, what[0].first, out);
Chris@16 684 }
Chris@16 685
Chris@16 686 out = what.format(out, format, flags);
Chris@16 687 cur = state.cur_ = state.next_search_ = what[0].second;
Chris@16 688
Chris@16 689 if(0 == (flags & format_first_only))
Chris@16 690 {
Chris@16 691 bool not_null = (0 == what.length());
Chris@16 692 state.reset(what, *access::get_regex_impl(re));
Chris@16 693 while(detail::regex_search_impl(state, re, not_null))
Chris@16 694 {
Chris@16 695 if(yes_copy)
Chris@16 696 {
Chris@16 697 out = std::copy(cur, what[0].first, out);
Chris@16 698 }
Chris@16 699
Chris@16 700 access::set_prefix_suffix(what, begin, end);
Chris@16 701 out = what.format(out, format, flags);
Chris@16 702 cur = state.cur_ = state.next_search_ = what[0].second;
Chris@16 703 not_null = (0 == what.length());
Chris@16 704 state.reset(what, *access::get_regex_impl(re));
Chris@16 705 }
Chris@16 706 }
Chris@16 707 }
Chris@16 708
Chris@16 709 if(yes_copy)
Chris@16 710 {
Chris@16 711 out = std::copy(cur, end, out);
Chris@16 712 }
Chris@16 713
Chris@16 714 return out;
Chris@16 715 }
Chris@16 716 } // namespace detail
Chris@16 717
Chris@16 718 /// \brief Build an output sequence given an input sequence, a regex, and a format string or
Chris@16 719 /// a formatter object, function, or expression.
Chris@16 720 ///
Chris@16 721 /// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
Chris@16 722 /// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
Chris@16 723 /// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
Chris@16 724 /// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
Chris@16 725 /// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
Chris@16 726 /// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
Chris@16 727 /// where \c last_m is a copy of the last match found.
Chris@16 728 ///
Chris@16 729 /// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
Chris@16 730 ///
Chris@16 731 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
Chris@16 732 /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
Chris@16 733 /// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
Chris@16 734 /// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
Chris@16 735 /// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
Chris@16 736 /// or else it is a null-terminated format string, or an expression template
Chris@16 737 /// representing a formatter lambda expression.
Chris@16 738 /// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
Chris@16 739 /// \param out An output iterator into which the output sequence is written.
Chris@16 740 /// \param begin The beginning of the input sequence.
Chris@16 741 /// \param end The end of the input sequence.
Chris@16 742 /// \param re The regular expression object to use.
Chris@16 743 /// \param format The format string used to format the replacement sequence,
Chris@16 744 /// or a formatter function, function object, or expression.
Chris@16 745 /// \param flags Optional match flags, used to control how the expression is matched against
Chris@16 746 /// the sequence. (See \c match_flag_type.)
Chris@16 747 /// \return The value of the output iterator after the output sequence has been written to it.
Chris@16 748 /// \throw regex_error on stack exhaustion or invalid format string.
Chris@16 749 template<typename OutIter, typename BidiIter, typename Formatter>
Chris@16 750 inline OutIter regex_replace
Chris@16 751 (
Chris@16 752 OutIter out
Chris@16 753 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 754 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 755 , basic_regex<BidiIter> const &re
Chris@16 756 , Formatter const &format
Chris@16 757 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 758 , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
Chris@16 759 )
Chris@16 760 {
Chris@16 761 // Default-constructed regexes match nothing
Chris@16 762 if(0 == re.regex_id())
Chris@16 763 {
Chris@16 764 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 765 {
Chris@16 766 out = std::copy(begin, end, out);
Chris@16 767 }
Chris@16 768
Chris@16 769 return out;
Chris@16 770 }
Chris@16 771
Chris@16 772 return detail::regex_replace_impl(out, begin, end, re, format, flags);
Chris@16 773 }
Chris@16 774
Chris@16 775 /// \overload
Chris@16 776 ///
Chris@16 777 template<typename OutIter, typename BidiIter>
Chris@16 778 inline OutIter regex_replace
Chris@16 779 (
Chris@16 780 OutIter out
Chris@16 781 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
Chris@16 782 , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
Chris@16 783 , basic_regex<BidiIter> const &re
Chris@16 784 , typename iterator_value<BidiIter>::type const *format
Chris@16 785 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 786 )
Chris@16 787 {
Chris@16 788 // Default-constructed regexes match nothing
Chris@16 789 if(0 == re.regex_id())
Chris@16 790 {
Chris@16 791 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 792 {
Chris@16 793 out = std::copy(begin, end, out);
Chris@16 794 }
Chris@16 795
Chris@16 796 return out;
Chris@16 797 }
Chris@16 798
Chris@16 799 return detail::regex_replace_impl(out, begin, end, re, format, flags);
Chris@16 800 }
Chris@16 801
Chris@16 802 /// \overload
Chris@16 803 ///
Chris@16 804 template<typename BidiContainer, typename BidiIter, typename Formatter>
Chris@16 805 inline BidiContainer regex_replace
Chris@16 806 (
Chris@16 807 BidiContainer &str
Chris@16 808 , basic_regex<BidiIter> const &re
Chris@16 809 , Formatter const &format
Chris@16 810 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 811 , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
Chris@16 812 )
Chris@16 813 {
Chris@16 814 BidiContainer result;
Chris@16 815 // Note that the result iterator of the range must be convertible
Chris@16 816 // to BidiIter here.
Chris@16 817 BidiIter begin = boost::begin(str), end = boost::end(str);
Chris@16 818
Chris@16 819 // Default-constructed regexes match nothing
Chris@16 820 if(0 == re.regex_id())
Chris@16 821 {
Chris@16 822 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 823 {
Chris@16 824 std::copy(begin, end, std::back_inserter(result));
Chris@16 825 }
Chris@16 826
Chris@16 827 return result;
Chris@16 828 }
Chris@16 829
Chris@16 830 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
Chris@16 831 return result;
Chris@16 832 }
Chris@16 833
Chris@16 834 /// \overload
Chris@16 835 ///
Chris@16 836 template<typename BidiContainer, typename BidiIter, typename Formatter>
Chris@16 837 inline BidiContainer regex_replace
Chris@16 838 (
Chris@16 839 BidiContainer const &str
Chris@16 840 , basic_regex<BidiIter> const &re
Chris@16 841 , Formatter const &format
Chris@16 842 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 843 , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
Chris@16 844 )
Chris@16 845 {
Chris@16 846 BidiContainer result;
Chris@16 847 // Note that the result iterator of the range must be convertible
Chris@16 848 // to BidiIter here.
Chris@16 849 BidiIter begin = boost::begin(str), end = boost::end(str);
Chris@16 850
Chris@16 851 // Default-constructed regexes match nothing
Chris@16 852 if(0 == re.regex_id())
Chris@16 853 {
Chris@16 854 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 855 {
Chris@16 856 std::copy(begin, end, std::back_inserter(result));
Chris@16 857 }
Chris@16 858
Chris@16 859 return result;
Chris@16 860 }
Chris@16 861
Chris@16 862 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
Chris@16 863 return result;
Chris@16 864 }
Chris@16 865
Chris@16 866 /// \overload
Chris@16 867 ///
Chris@16 868 template<typename Char, typename Formatter>
Chris@16 869 inline std::basic_string<typename remove_const<Char>::type> regex_replace
Chris@16 870 (
Chris@16 871 BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
Chris@16 872 , basic_regex<Char *> const &re
Chris@16 873 , Formatter const &format
Chris@16 874 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 875 , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
Chris@16 876 )
Chris@16 877 {
Chris@16 878 typedef typename remove_const<Char>::type char_type;
Chris@16 879 std::basic_string<char_type> result;
Chris@16 880
Chris@16 881 // Default-constructed regexes match nothing
Chris@16 882 if(0 == re.regex_id())
Chris@16 883 {
Chris@16 884 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 885 {
Chris@16 886 result = str;
Chris@16 887 }
Chris@16 888
Chris@16 889 return result;
Chris@16 890 }
Chris@16 891
Chris@16 892 Char *end = str + std::char_traits<char_type>::length(str);
Chris@16 893 detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
Chris@16 894 return result;
Chris@16 895 }
Chris@16 896
Chris@16 897 /// \overload
Chris@16 898 ///
Chris@16 899 template<typename BidiContainer, typename BidiIter>
Chris@16 900 inline BidiContainer regex_replace
Chris@16 901 (
Chris@16 902 BidiContainer &str
Chris@16 903 , basic_regex<BidiIter> const &re
Chris@16 904 , typename iterator_value<BidiIter>::type const *format
Chris@16 905 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 906 , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
Chris@16 907 )
Chris@16 908 {
Chris@16 909 BidiContainer result;
Chris@16 910 // Note that the result iterator of the range must be convertible
Chris@16 911 // to BidiIter here.
Chris@16 912 BidiIter begin = boost::begin(str), end = boost::end(str);
Chris@16 913
Chris@16 914 // Default-constructed regexes match nothing
Chris@16 915 if(0 == re.regex_id())
Chris@16 916 {
Chris@16 917 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 918 {
Chris@16 919 std::copy(begin, end, std::back_inserter(result));
Chris@16 920 }
Chris@16 921
Chris@16 922 return result;
Chris@16 923 }
Chris@16 924
Chris@16 925 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
Chris@16 926 return result;
Chris@16 927 }
Chris@16 928
Chris@16 929 /// \overload
Chris@16 930 ///
Chris@16 931 template<typename BidiContainer, typename BidiIter>
Chris@16 932 inline BidiContainer regex_replace
Chris@16 933 (
Chris@16 934 BidiContainer const &str
Chris@16 935 , basic_regex<BidiIter> const &re
Chris@16 936 , typename iterator_value<BidiIter>::type const *format
Chris@16 937 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 938 , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
Chris@16 939 )
Chris@16 940 {
Chris@16 941 BidiContainer result;
Chris@16 942 // Note that the result iterator of the range must be convertible
Chris@16 943 // to BidiIter here.
Chris@16 944 BidiIter begin = boost::begin(str), end = boost::end(str);
Chris@16 945
Chris@16 946 // Default-constructed regexes match nothing
Chris@16 947 if(0 == re.regex_id())
Chris@16 948 {
Chris@16 949 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 950 {
Chris@16 951 std::copy(begin, end, std::back_inserter(result));
Chris@16 952 }
Chris@16 953
Chris@16 954 return result;
Chris@16 955 }
Chris@16 956
Chris@16 957 detail::regex_replace_impl(std::back_inserter(result), begin, end, re, format, flags);
Chris@16 958 return result;
Chris@16 959 }
Chris@16 960
Chris@16 961 /// \overload
Chris@16 962 ///
Chris@16 963 template<typename Char>
Chris@16 964 inline std::basic_string<typename remove_const<Char>::type> regex_replace
Chris@16 965 (
Chris@16 966 BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
Chris@16 967 , basic_regex<Char *> const &re
Chris@16 968 , typename add_const<Char>::type *format
Chris@16 969 , regex_constants::match_flag_type flags = regex_constants::match_default
Chris@16 970 )
Chris@16 971 {
Chris@16 972 typedef typename remove_const<Char>::type char_type;
Chris@16 973 std::basic_string<char_type> result;
Chris@16 974
Chris@16 975 // Default-constructed regexes match nothing
Chris@16 976 if(0 == re.regex_id())
Chris@16 977 {
Chris@16 978 if((0 == (flags & regex_constants::format_no_copy)))
Chris@16 979 {
Chris@16 980 result = str;
Chris@16 981 }
Chris@16 982
Chris@16 983 return result;
Chris@16 984 }
Chris@16 985
Chris@16 986 Char *end = str + std::char_traits<char_type>::length(str);
Chris@16 987 detail::regex_replace_impl(std::back_inserter(result), str, end, re, format, flags);
Chris@16 988 return result;
Chris@16 989 }
Chris@16 990
Chris@16 991 }} // namespace boost::xpressive
Chris@16 992
Chris@16 993 #endif