]> git.lyx.org Git - lyx.git/blob - boost/boost/regex/v4/regex_split.hpp
update to boost 1.34
[lyx.git] / boost / boost / regex / v4 / regex_split.hpp
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
24 namespace boost{
25
26 #ifdef BOOST_HAS_ABI_HEADERS
27 #  include BOOST_ABI_PREFIX
28 #endif
29
30 namespace re_detail{
31
32 template <class charT>
33 const 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
40 template <class OutputIterator, class charT, class Traits1, class Alloc1>
41 class 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;
49 public:
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
56 template <class OutputIterator, class charT, class Traits1, class Alloc1>
57 bool 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
90 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
91 std::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
125 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
126 inline 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
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)
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