1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#ifndef ParameterSet_split_h
#define ParameterSet_split_h
// ----------------------------------------------------------------------
// definition of split() and related templates
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// prolog
// ----------------------------------------------------------------------
// prerequisite source files and headers
#include <string_view>
// ----------------------------------------------------------------------
// contents
namespace edm {
template <class FwdIter>
FwdIter contextual_find(FwdIter b, FwdIter e, char first, char sep, char last);
template <class FwdIter>
FwdIter contextual_find_not(FwdIter b, FwdIter e, char first, char sep, char last);
template <class OutIter>
bool split(OutIter result, std::string_view string_to_split, char first, char sep, char last);
template <typename FUNC>
bool split(std::string_view string_to_split, char first, char sep, char last, FUNC f);
} // namespace edm
// ----------------------------------------------------------------------
// contextual_find
template <class FwdIter>
FwdIter edm::contextual_find(FwdIter b, FwdIter e, char first, char sep, char last) {
for (int nested = 0; b != e; ++b) {
if (*b == first)
++nested;
else if (*b == last)
--nested;
else if (*b == sep && nested == 0)
return b;
}
return e;
} // contextual_find()
// ----------------------------------------------------------------------
// contextual_find_not
template <class FwdIter>
FwdIter edm::contextual_find_not(FwdIter b, FwdIter e, char /* first */, char sep, char /* last */) {
for (; b != e; ++b) {
if (*b != sep)
return b;
}
return e;
} // contextual_find_not()
// ----------------------------------------------------------------------
// split()
template <class OutIter>
bool edm::split(OutIter dest, std::string_view s, char first, char sep, char last) {
using str_c_iter = std::string_view::const_iterator;
str_c_iter b = s.cbegin(), e = s.cend();
if (static_cast<unsigned int>(e - b) < 2u)
return false;
if (*b == first)
++b;
else
return false;
if (*--e != last)
return false;
// invariant: we've found all items in [b..boi)
for (str_c_iter //boi = std::find_if(b, e, is_not_a(sep))
boi = contextual_find_not(b, e, first, sep, last),
eoi;
boi != e
//; boi = std::find_if(eoi, e, is_not_a(sep))
;
boi = contextual_find_not(eoi, e, first, sep, last)) {
// find end of current item:
//eoi = std::find_if(boi, e, is_a(sep));
eoi = contextual_find(boi, e, first, sep, last);
// copy the item formed from characters in [boi..eoi):
*dest++ = std::string_view(boi, eoi - boi);
} // for
return true;
} // split< >()
template <typename FUNC>
bool edm::split(std::string_view s, char first, char sep, char last, FUNC f) {
using str_c_iter = std::string_view::const_iterator;
str_c_iter b = s.cbegin(), e = s.cend();
if (static_cast<unsigned int>(e - b) < 2u)
return false;
if (*b == first)
++b;
else
return false;
if (*--e != last)
return false;
// invariant: we've found all items in [b..boi)
for (str_c_iter boi = contextual_find_not(b, e, first, sep, last), eoi; boi != e;
boi = contextual_find_not(eoi, e, first, sep, last)) {
// find end of current item:
eoi = contextual_find(boi, e, first, sep, last);
// copy the item formed from characters in [boi..eoi):
if (not f(std::string_view(boi, eoi - boi))) {
return false;
}
} // for
return true;
} // split< >()
// ----------------------------------------------------------------------
// epilog
#endif
|