]> git.ipfire.org Git - thirdparty/squid.git/blob - src/SBufAlgos.h
Prep for 3.3.12 and 3.4.4
[thirdparty/squid.git] / src / SBufAlgos.h
1 #ifndef SQUID_SBUFALGOS_H_
2 #define SQUID_SBUFALGOS_H_
3
4 #include "SBuf.h"
5
6 #include <algorithm>
7 #include <numeric>
8
9 /// SBuf equality predicate for STL algorithms etc
10 class SBufEqual
11 {
12 public:
13 explicit SBufEqual(const SBuf &reference, SBufCaseSensitive sensitivity = caseSensitive) :
14 reference_(reference), sensitivity_(sensitivity) {}
15 bool operator() (const SBuf & checking) { return checking.compare(reference_,sensitivity_) == 0; }
16 private:
17 SBuf reference_;
18 SBufCaseSensitive sensitivity_;
19 };
20
21 /// SBuf "starts with" predicate for STL algorithms etc
22 class SBufStartsWith
23 {
24 public:
25 explicit SBufStartsWith(const SBuf &prefix, SBufCaseSensitive sensitivity = caseSensitive) :
26 prefix_(prefix), sensitivity_(sensitivity) {}
27 bool operator() (const SBuf & checking) { return checking.startsWith(prefix_,sensitivity_); }
28 private:
29 SBuf prefix_;
30 SBufCaseSensitive sensitivity_;
31 };
32
33 /** SBuf size addition accumulator for STL contaniners
34 *
35 * Equivalent to prefix_length + SBuf.length() + separator.length()
36 */
37 class SBufAddLength
38 {
39 public:
40 explicit SBufAddLength(const SBuf &separator) :
41 separatorLen_(separator.length()) {}
42 SBuf::size_type operator()(const SBuf::size_type sz, const SBuf & item) {
43 return sz + item.length() + separatorLen_;
44 }
45 private:
46 SBuf::size_type separatorLen_;
47 };
48
49 /// join all the SBuf in a container of SBuf into a single SBuf, separating with separator
50 template <class Container>
51 SBuf
52 SBufContainerJoin(const Container &items, const SBuf& separator)
53 {
54 // optimization: pre-calculate needed storage
55 const SBuf::size_type sz = std::accumulate(items.begin(), items.end(), 0, SBufAddLength(separator));
56
57 // sz can be zero in two cases: either items is empty, or all items
58 // are zero-length. In the former case, we must protect against
59 // dereferencing the iterator later on, and checking sz is more efficient
60 // than checking items.size(). This check also provides an optimization
61 // for the latter case without adding complexity.
62 if (sz == 0)
63 return SBuf();
64
65 SBuf rv;
66 rv.reserveSpace(sz);
67
68 typename Container::const_iterator i(items.begin());
69 rv.append(*i);
70 ++i;
71 for (; i != items.end(); ++i)
72 rv.append(separator).append(*i);
73 return rv;
74 }
75
76 #endif /* SQUID_SBUFALGOS_H_ */