| /* |
| * |
| * Copyright (c) 1998-2002 |
| * John Maddock |
| * |
| * Use, modification and distribution are subject to the |
| * Boost Software License, Version 1.0. (See accompanying file |
| * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| * |
| */ |
| |
| /* |
| * LOCATION: see http://www.boost.org for most recent version. |
| * FILE regex_split.hpp |
| * VERSION see <ndnboost/version.hpp> |
| * DESCRIPTION: Implements regex_split and associated functions. |
| * Note this is an internal header file included |
| * by regex.hpp, do not include on its own. |
| */ |
| |
| #ifndef NDNBOOST_REGEX_SPLIT_HPP |
| #define NDNBOOST_REGEX_SPLIT_HPP |
| |
| namespace ndnboost{ |
| |
| #ifdef NDNBOOST_MSVC |
| #pragma warning(push) |
| #pragma warning(disable: 4103) |
| #endif |
| #ifdef NDNBOOST_HAS_ABI_HEADERS |
| # include NDNBOOST_ABI_PREFIX |
| #endif |
| #ifdef NDNBOOST_MSVC |
| #pragma warning(pop) |
| #endif |
| |
| #ifdef NDNBOOST_MSVC |
| # pragma warning(push) |
| # pragma warning(disable: 4800) |
| #endif |
| |
| namespace re_detail{ |
| |
| template <class charT> |
| const basic_regex<charT>& get_default_expression(charT) |
| { |
| static const charT expression_text[4] = { '\\', 's', '+', '\00', }; |
| static const basic_regex<charT> e(expression_text); |
| return e; |
| } |
| |
| template <class OutputIterator, class charT, class Traits1, class Alloc1> |
| class split_pred |
| { |
| typedef std::basic_string<charT, Traits1, Alloc1> string_type; |
| typedef typename string_type::const_iterator iterator_type; |
| iterator_type* p_last; |
| OutputIterator* p_out; |
| std::size_t* p_max; |
| std::size_t initial_max; |
| public: |
| split_pred(iterator_type* a, OutputIterator* b, std::size_t* c) |
| : p_last(a), p_out(b), p_max(c), initial_max(*c) {} |
| |
| bool operator()(const match_results<iterator_type>& what); |
| }; |
| |
| template <class OutputIterator, class charT, class Traits1, class Alloc1> |
| bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator() |
| (const match_results<iterator_type>& what) |
| { |
| *p_last = what[0].second; |
| if(what.size() > 1) |
| { |
| // output sub-expressions only: |
| for(unsigned i = 1; i < what.size(); ++i) |
| { |
| *(*p_out) = what.str(i); |
| ++(*p_out); |
| if(0 == --*p_max) return false; |
| } |
| return *p_max != 0; |
| } |
| else |
| { |
| // output $` only if it's not-null or not at the start of the input: |
| const sub_match<iterator_type>& sub = what[-1]; |
| if((sub.first != sub.second) || (*p_max != initial_max)) |
| { |
| *(*p_out) = sub.str(); |
| ++(*p_out); |
| return --*p_max; |
| } |
| } |
| // |
| // initial null, do nothing: |
| return true; |
| } |
| |
| } // namespace re_detail |
| |
| template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2> |
| std::size_t regex_split(OutputIterator out, |
| std::basic_string<charT, Traits1, Alloc1>& s, |
| const basic_regex<charT, Traits2>& e, |
| match_flag_type flags, |
| std::size_t max_split) |
| { |
| typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t; |
| //typedef typename match_results<ci_t>::allocator_type match_allocator; |
| ci_t last = s.begin(); |
| std::size_t init_size = max_split; |
| re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split); |
| ci_t i, j; |
| i = s.begin(); |
| j = s.end(); |
| regex_grep(pred, i, j, e, flags); |
| // |
| // if there is still input left, do a final push as long as max_split |
| // is not exhausted, and we're not splitting sub-expressions rather |
| // than whitespace: |
| if(max_split && (last != s.end()) && (e.mark_count() == 1)) |
| { |
| *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end()); |
| ++out; |
| last = s.end(); |
| --max_split; |
| } |
| // |
| // delete from the string everything that has been processed so far: |
| s.erase(0, last - s.begin()); |
| // |
| // return the number of new records pushed: |
| return init_size - max_split; |
| } |
| |
| template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2> |
| inline std::size_t regex_split(OutputIterator out, |
| std::basic_string<charT, Traits1, Alloc1>& s, |
| const basic_regex<charT, Traits2>& e, |
| match_flag_type flags = match_default) |
| { |
| return regex_split(out, s, e, flags, UINT_MAX); |
| } |
| |
| template <class OutputIterator, class charT, class Traits1, class Alloc1> |
| inline std::size_t regex_split(OutputIterator out, |
| std::basic_string<charT, Traits1, Alloc1>& s) |
| { |
| return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX); |
| } |
| |
| #ifdef NDNBOOST_MSVC |
| # pragma warning(pop) |
| #endif |
| |
| #ifdef NDNBOOST_MSVC |
| #pragma warning(push) |
| #pragma warning(disable: 4103) |
| #endif |
| #ifdef NDNBOOST_HAS_ABI_HEADERS |
| # include NDNBOOST_ABI_SUFFIX |
| #endif |
| #ifdef NDNBOOST_MSVC |
| #pragma warning(pop) |
| #endif |
| |
| } // namespace ndnboost |
| |
| #endif |
| |
| |