blob: cdc67b3e25d336bc8867b8522d81fc1788652072 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001/*
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 <ndnboost/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 NDNBOOST_REGEX_SPLIT_HPP
22#define NDNBOOST_REGEX_SPLIT_HPP
23
24namespace ndnboost{
25
26#ifdef NDNBOOST_MSVC
27#pragma warning(push)
28#pragma warning(disable: 4103)
29#endif
30#ifdef NDNBOOST_HAS_ABI_HEADERS
31# include NDNBOOST_ABI_PREFIX
32#endif
33#ifdef NDNBOOST_MSVC
34#pragma warning(pop)
35#endif
36
37#ifdef NDNBOOST_MSVC
38# pragma warning(push)
39# pragma warning(disable: 4800)
40#endif
41
42namespace re_detail{
43
44template <class charT>
45const basic_regex<charT>& get_default_expression(charT)
46{
47 static const charT expression_text[4] = { '\\', 's', '+', '\00', };
48 static const basic_regex<charT> e(expression_text);
49 return e;
50}
51
52template <class OutputIterator, class charT, class Traits1, class Alloc1>
53class split_pred
54{
55 typedef std::basic_string<charT, Traits1, Alloc1> string_type;
56 typedef typename string_type::const_iterator iterator_type;
57 iterator_type* p_last;
58 OutputIterator* p_out;
59 std::size_t* p_max;
60 std::size_t initial_max;
61public:
62 split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
63 : p_last(a), p_out(b), p_max(c), initial_max(*c) {}
64
65 bool operator()(const match_results<iterator_type>& what);
66};
67
68template <class OutputIterator, class charT, class Traits1, class Alloc1>
69bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
70 (const match_results<iterator_type>& what)
71{
72 *p_last = what[0].second;
73 if(what.size() > 1)
74 {
75 // output sub-expressions only:
76 for(unsigned i = 1; i < what.size(); ++i)
77 {
78 *(*p_out) = what.str(i);
79 ++(*p_out);
80 if(0 == --*p_max) return false;
81 }
82 return *p_max != 0;
83 }
84 else
85 {
86 // output $` only if it's not-null or not at the start of the input:
87 const sub_match<iterator_type>& sub = what[-1];
88 if((sub.first != sub.second) || (*p_max != initial_max))
89 {
90 *(*p_out) = sub.str();
91 ++(*p_out);
92 return --*p_max;
93 }
94 }
95 //
96 // initial null, do nothing:
97 return true;
98}
99
100} // namespace re_detail
101
102template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
103std::size_t regex_split(OutputIterator out,
104 std::basic_string<charT, Traits1, Alloc1>& s,
105 const basic_regex<charT, Traits2>& e,
106 match_flag_type flags,
107 std::size_t max_split)
108{
109 typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
110 //typedef typename match_results<ci_t>::allocator_type match_allocator;
111 ci_t last = s.begin();
112 std::size_t init_size = max_split;
113 re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);
114 ci_t i, j;
115 i = s.begin();
116 j = s.end();
117 regex_grep(pred, i, j, e, flags);
118 //
119 // if there is still input left, do a final push as long as max_split
120 // is not exhausted, and we're not splitting sub-expressions rather
121 // than whitespace:
122 if(max_split && (last != s.end()) && (e.mark_count() == 1))
123 {
124 *out = std::basic_string<charT, Traits1, Alloc1>((ci_t)last, (ci_t)s.end());
125 ++out;
126 last = s.end();
127 --max_split;
128 }
129 //
130 // delete from the string everything that has been processed so far:
131 s.erase(0, last - s.begin());
132 //
133 // return the number of new records pushed:
134 return init_size - max_split;
135}
136
137template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
138inline std::size_t regex_split(OutputIterator out,
139 std::basic_string<charT, Traits1, Alloc1>& s,
140 const basic_regex<charT, Traits2>& e,
141 match_flag_type flags = match_default)
142{
143 return regex_split(out, s, e, flags, UINT_MAX);
144}
145
146template <class OutputIterator, class charT, class Traits1, class Alloc1>
147inline std::size_t regex_split(OutputIterator out,
148 std::basic_string<charT, Traits1, Alloc1>& s)
149{
150 return regex_split(out, s, re_detail::get_default_expression(charT(0)), match_default, UINT_MAX);
151}
152
153#ifdef NDNBOOST_MSVC
154# pragma warning(pop)
155#endif
156
157#ifdef NDNBOOST_MSVC
158#pragma warning(push)
159#pragma warning(disable: 4103)
160#endif
161#ifdef NDNBOOST_HAS_ABI_HEADERS
162# include NDNBOOST_ABI_SUFFIX
163#endif
164#ifdef NDNBOOST_MSVC
165#pragma warning(pop)
166#endif
167
168} // namespace ndnboost
169
170#endif
171
172