3 * Copyright (c) 1998-2002
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE regex_split.hpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Implements regex_split and associated functions.
17 * Note this is an internal header file included
18 * by regex.hpp, do not include on its own.
21 #ifndef BOOST_REGEX_SPLIT_HPP
22 #define BOOST_REGEX_SPLIT_HPP
26 #ifdef BOOST_HAS_ABI_HEADERS
27 # include BOOST_ABI_PREFIX
32 template <class charT>
33 const reg_expression<charT>& get_default_expression(charT)
35 static const charT expression_text[4] = { '\\', 's', '+', '\00', };
36 static const reg_expression<charT> e(expression_text);
40 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
43 typedef std::basic_string<charT, Traits1, Alloc1> string_type;
44 typedef typename string_type::const_iterator iterator_type;
45 iterator_type* p_last;
46 OutputIterator* p_out;
48 std::size_t initial_max;
50 split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
51 : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
53 bool operator()(const match_results<iterator_type, Alloc2>& what);
56 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
57 bool split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2>::operator()
58 (const match_results<iterator_type, Alloc2>& what)
60 *p_last = what[0].second;
63 // output sub-expressions only:
64 for(unsigned i = 1; i < what.size(); ++i)
66 *(*p_out) = static_cast<string_type>(what[i]);
68 if(0 == --*p_max) return false;
74 // output $` only if it's not-null or not at the start of the input:
75 const sub_match<iterator_type>& sub = what[-1];
76 if((sub.first != sub.second) || (*p_max != initial_max))
78 *(*p_out) = static_cast<string_type>(sub);
84 // initial null, do nothing:
88 } // namespace re_detail
90 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
91 std::size_t regex_split(OutputIterator out,
92 std::basic_string<charT, Traits1, Alloc1>& s,
93 const reg_expression<charT, Traits2, Alloc2>& e,
94 match_flag_type flags,
95 std::size_t max_split)
97 typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
98 typedef typename detail::rebind_allocator<sub_match<ci_t>, Alloc2>::type match_allocator;
99 ci_t last = s.begin();
100 std::size_t init_size = max_split;
101 re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1, match_allocator> pred(&last, &out, &max_split);
105 regex_grep(pred, i, j, e, flags);
107 // if there is still input left, do a final push as long as max_split
108 // is not exhausted, and we're not splitting sub-expressions rather
110 if(max_split && (last != s.end()) && (e.mark_count() == 1))
112 *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
118 // delete from the string everything that has been processed so far:
119 s.erase(0, last - s.begin());
121 // return the number of new records pushed:
122 return init_size - max_split;
125 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
126 inline std::size_t regex_split(OutputIterator out,
127 std::basic_string<charT, Traits1, Alloc1>& s,
128 const reg_expression<charT, Traits2, Alloc2>& e,
129 match_flag_type flags = match_default)
131 return regex_split(out, s, e, flags, UINT_MAX);
134 template <class OutputIterator, class charT, class Traits1, class Alloc1>
135 inline std::size_t regex_split(OutputIterator out,
136 std::basic_string<charT, Traits1, Alloc1>& s)
138 return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
141 #ifdef BOOST_HAS_ABI_HEADERS
142 # include BOOST_ABI_SUFFIX