]> git.lyx.org Git - lyx.git/blob - boost/boost/regex/detail/regex_split.hpp
update
[lyx.git] / boost / boost / regex / detail / regex_split.hpp
1 /*
2  *
3  * Copyright (c) 1998-2002
4  * Dr John Maddock
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Dr John Maddock makes no representations
11  * about the suitability of this software for any purpose.  
12  * It is provided "as is" without express or implied warranty.
13  *
14  */
15  
16  /*
17   *   LOCATION:    see http://www.boost.org for most recent version.
18   *   FILE         regex_split.hpp
19   *   VERSION      see <boost/version.hpp>
20   *   DESCRIPTION: Implements regex_split and associated functions.
21   *                Note this is an internal header file included
22   *                by regex.hpp, do not include on its own.
23   */
24
25 #ifndef BOOST_REGEX_SPLIT_HPP
26 #define BOOST_REGEX_SPLIT_HPP
27
28 namespace boost{
29
30 #ifdef __BORLANDC__
31    #pragma option push -a8 -b -Vx -Ve -pc
32 #endif
33
34 namespace re_detail{
35
36 template <class charT>
37 const reg_expression<charT>& get_default_expression(charT)
38 {
39    static const charT expression_text[] = { '\\', 's', '+', '\00', };
40    static const reg_expression<charT> e(expression_text);
41    return e;
42 }
43
44 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
45 class split_pred
46 {
47    typedef std::basic_string<charT, Traits1, Alloc1> string_type;
48    typedef typename string_type::const_iterator iterator_type;
49    iterator_type* p_last;
50    OutputIterator* p_out;
51    std::size_t* p_max;
52    std::size_t initial_max;
53 public:
54    split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
55       : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
56
57    bool operator()(const match_results<iterator_type, Alloc2>& what);
58 };
59
60 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
61 bool split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2>::operator()
62    (const match_results<iterator_type, Alloc2>& what)
63 {
64    *p_last = what[0].second;
65    if(what.size() > 1)
66    {
67       // output sub-expressions only:
68       for(unsigned i = 1; i < what.size(); ++i)
69       {
70          *(*p_out) = static_cast<string_type>(what[i]);
71          ++(*p_out);
72          if(0 == --*p_max) return false;
73       }
74       return *p_max != 0;
75    }
76    else
77    {
78       // output $` only if it's not-null or not at the start of the input:
79       const sub_match<iterator_type>& sub = what[-1];
80       if((sub.first != sub.second) || (*p_max != initial_max))
81       {
82          *(*p_out) = static_cast<string_type>(sub);
83          ++(*p_out);
84          return --*p_max;
85       }
86    }
87    //
88    // initial null, do nothing:
89    return true;
90 }
91
92 } // namespace re_detail
93
94 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
95 std::size_t regex_split(OutputIterator out,
96                    std::basic_string<charT, Traits1, Alloc1>& s, 
97                    const reg_expression<charT, Traits2, Alloc2>& e,
98                    unsigned flags,
99                    std::size_t max_split)
100 {
101    typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
102    ci_t last = s.begin();
103    std::size_t init_size = max_split;
104    re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2> pred(&last, &out, &max_split);
105    ci_t i, j;
106    i = s.begin();
107    j = s.end();
108    regex_grep(pred, i, j, e, flags);
109    //
110    // if there is still input left, do a final push as long as max_split
111    // is not exhausted, and we're not splitting sub-expressions rather 
112    // than whitespace:
113    if(max_split && (last != s.end()) && (e.mark_count() == 1))
114    {
115       *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
116       ++out;
117       last = s.end();
118       --max_split;
119    }
120    //
121    // delete from the string everything that has been processed so far:
122    s.erase(0, last - s.begin());
123    //
124    // return the number of new records pushed:
125    return init_size - max_split;
126 }
127
128 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
129 inline std::size_t regex_split(OutputIterator out,
130                    std::basic_string<charT, Traits1, Alloc1>& s, 
131                    const reg_expression<charT, Traits2, Alloc2>& e,
132                    unsigned flags = match_default)
133 {
134    return regex_split(out, s, e, flags, UINT_MAX);
135 }
136
137 template <class OutputIterator, class charT, class Traits1, class Alloc1>
138 inline std::size_t regex_split(OutputIterator out,
139                    std::basic_string<charT, Traits1, Alloc1>& s)
140 {
141    return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
142 }
143
144 #ifdef __BORLANDC__
145   #pragma option pop
146 #endif
147
148 } // namespace boost
149
150 #endif
151