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