source: NonGTP/Boost/boost/regex/v4/regex_split.hpp @ 857

Revision 857, 4.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*
2 *
3 * Copyright (c) 1998-2002
4 * John Maddock
5 *
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)
9 *
10 */
11 
12 /*
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.
19  */
20
21#ifndef BOOST_REGEX_SPLIT_HPP
22#define BOOST_REGEX_SPLIT_HPP
23
24namespace boost{
25
26#ifdef BOOST_HAS_ABI_HEADERS
27#  include BOOST_ABI_PREFIX
28#endif
29
30namespace re_detail{
31
32template <class charT>
33const basic_regex<charT>& get_default_expression(charT)
34{
35   static const charT expression_text[4] = { '\\', 's', '+', '\00', };
36   static const basic_regex<charT> e(expression_text);
37   return e;
38}
39
40template <class OutputIterator, class charT, class Traits1, class Alloc1>
41class split_pred
42{
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;
47   std::size_t* p_max;
48   std::size_t initial_max;
49public:
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) {}
52
53   bool operator()(const match_results<iterator_type>& what);
54};
55
56template <class OutputIterator, class charT, class Traits1, class Alloc1>
57bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
58   (const match_results<iterator_type>& what)
59{
60   *p_last = what[0].second;
61   if(what.size() > 1)
62   {
63      // output sub-expressions only:
64      for(unsigned i = 1; i < what.size(); ++i)
65      {
66         *(*p_out) = what.str(i);
67         ++(*p_out);
68         if(0 == --*p_max) return false;
69      }
70      return *p_max != 0;
71   }
72   else
73   {
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))
77      {
78         *(*p_out) = sub.str();
79         ++(*p_out);
80         return --*p_max;
81      }
82   }
83   //
84   // initial null, do nothing:
85   return true;
86}
87
88} // namespace re_detail
89
90template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
91std::size_t regex_split(OutputIterator out,
92                   std::basic_string<charT, Traits1, Alloc1>& s,
93                   const basic_regex<charT, Traits2>& e,
94                   match_flag_type flags,
95                   std::size_t max_split)
96{
97   typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator  ci_t;
98   typedef typename match_results<ci_t>::allocator_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> pred(&last, &out, &max_split);
102   ci_t i, j;
103   i = s.begin();
104   j = s.end();
105   regex_grep(pred, i, j, e, flags);
106   //
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
109   // than whitespace:
110   if(max_split && (last != s.end()) && (e.mark_count() == 1))
111   {
112      *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
113      ++out;
114      last = s.end();
115      --max_split;
116   }
117   //
118   // delete from the string everything that has been processed so far:
119   s.erase(0, last - s.begin());
120   //
121   // return the number of new records pushed:
122   return init_size - max_split;
123}
124
125template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
126inline std::size_t regex_split(OutputIterator out,
127                   std::basic_string<charT, Traits1, Alloc1>& s,
128                   const basic_regex<charT, Traits2>& e,
129                   match_flag_type flags = match_default)
130{
131   return regex_split(out, s, e, flags, UINT_MAX);
132}
133
134template <class OutputIterator, class charT, class Traits1, class Alloc1>
135inline std::size_t regex_split(OutputIterator out,
136                   std::basic_string<charT, Traits1, Alloc1>& s)
137{
138   return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
139}
140
141#ifdef BOOST_HAS_ABI_HEADERS
142#  include BOOST_ABI_SUFFIX
143#endif
144
145} // namespace boost
146
147#endif
148
149
Note: See TracBrowser for help on using the repository browser.