]> git.lyx.org Git - lyx.git/blob - boost/boost/re_detail/regex_split.hpp
cvsignore ++
[lyx.git] / boost / boost / re_detail / regex_split.hpp
1 /*
2  *
3  * Copyright (c) 1998-2000
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      3.03
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    #if __BORLANDC__ == 0x530
32     #pragma option push -a4 -b -Ve
33    #elif __BORLANDC__ > 0x530
34     #pragma option push -a8 -b -Ve
35    #endif
36 #endif
37
38 namespace re_detail{
39
40 template <class charT>
41 const reg_expression<charT>& get_default_expression(charT)
42 {
43    static const charT expression_text[] = { '\\', 's', '+', '\00', };
44    static const reg_expression<charT> e(expression_text);
45    return e;
46 }
47
48 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
49 class split_pred
50 {
51    typedef std::basic_string<charT, Traits1, Alloc1> string_type;
52    typedef typename string_type::const_iterator iterator_type;
53    iterator_type* p_last;
54    OutputIterator* p_out;
55    std::size_t* p_max;
56    std::size_t initial_max;
57 public:
58    split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
59       : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
60
61    bool operator()(const match_results<iterator_type, Alloc2>& what);
62 };
63
64 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
65 bool split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2>::operator()
66    (const match_results<iterator_type, Alloc2>& what)
67 {
68    *p_last = what[0].second;
69    if(what.size() > 1)
70    {
71       // output sub-expressions only:
72       for(unsigned i = 1; i < what.size(); ++i)
73       {
74          *(*p_out) = static_cast<string_type>(what[i]);
75          ++(*p_out);
76          return --*p_max;
77       }
78    }
79    else
80    {
81       // output $` only if it's not-null or not at the start of the input:
82       const sub_match<iterator_type>& sub = what[-1];
83       if((sub.first != sub.second) || (*p_max != initial_max))
84       {
85          *(*p_out) = static_cast<string_type>(sub);
86          ++(*p_out);
87          return --*p_max;
88       }
89    }
90    //
91    // initial null, do nothing:
92    return true;
93 }
94
95 } // namespace re_detail
96
97 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
98 std::size_t regex_split(OutputIterator out,
99                    std::basic_string<charT, Traits1, Alloc1>& s, 
100                    const reg_expression<charT, Traits2, Alloc2>& e,
101                    unsigned flags,
102                    std::size_t max_split)
103 {
104    typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
105    ci_t last = s.begin();
106    std::size_t init_size = max_split;
107    re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2> pred(&last, &out, &max_split);
108    ci_t i, j;
109    i = s.begin();
110    j = s.end();
111    regex_grep(pred, i, j, e, flags);
112    //
113    // if there is still input left, do a final push as long as max_split
114    // is not exhausted, and we're not splitting sub-expressions rather 
115    // than whitespace:
116    if(max_split && (last != s.end()) && (e.mark_count() == 1))
117    {
118       *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
119       ++out;
120       last = s.end();
121       --max_split;
122    }
123    //
124    // delete from the string everything that has been processed so far:
125    s.erase(0, last - s.begin());
126    //
127    // return the number of new records pushed:
128    return init_size - max_split;
129 }
130
131 template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
132 inline std::size_t regex_split(OutputIterator out,
133                    std::basic_string<charT, Traits1, Alloc1>& s, 
134                    const reg_expression<charT, Traits2, Alloc2>& e,
135                    unsigned flags = match_default)
136 {
137    return regex_split(out, s, e, flags, UINT_MAX);
138 }
139
140 template <class OutputIterator, class charT, class Traits1, class Alloc1>
141 inline std::size_t regex_split(OutputIterator out,
142                    std::basic_string<charT, Traits1, Alloc1>& s)
143 {
144    return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
145 }
146
147 #ifdef __BORLANDC__
148  #if __BORLANDC__ > 0x520
149   #pragma option pop
150  #endif
151 #endif
152
153 } // namespace boost
154
155 #endif