]>
Commit | Line | Data |
---|---|---|
bbc27441 AJ |
1 | /* |
2 | * Copyright (C) 1996-2014 The Squid Software Foundation and contributors | |
3 | * | |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
6a17a36d FC |
9 | #ifndef SQUID_SBUFALGOS_H_ |
10 | #define SQUID_SBUFALGOS_H_ | |
11 | ||
12 | #include "SBuf.h" | |
2d2e4881 | 13 | |
6a17a36d | 14 | #include <algorithm> |
67083a4d | 15 | #include <numeric> |
6a17a36d FC |
16 | |
17 | /// SBuf equality predicate for STL algorithms etc | |
514fc315 FC |
18 | class SBufEqual |
19 | { | |
6a17a36d | 20 | public: |
514fc315 | 21 | explicit SBufEqual(const SBuf &reference, SBufCaseSensitive sensitivity = caseSensitive) : |
86c63190 | 22 | reference_(reference), sensitivity_(sensitivity) {} |
514fc315 | 23 | bool operator() (const SBuf & checking) { return checking.compare(reference_,sensitivity_) == 0; } |
6a17a36d FC |
24 | private: |
25 | SBuf reference_; | |
26 | SBufCaseSensitive sensitivity_; | |
27 | }; | |
28 | ||
29 | /// SBuf "starts with" predicate for STL algorithms etc | |
514fc315 FC |
30 | class SBufStartsWith |
31 | { | |
6a17a36d | 32 | public: |
514fc315 | 33 | explicit SBufStartsWith(const SBuf &prefix, SBufCaseSensitive sensitivity = caseSensitive) : |
86c63190 | 34 | prefix_(prefix), sensitivity_(sensitivity) {} |
514fc315 | 35 | bool operator() (const SBuf & checking) { return checking.startsWith(prefix_,sensitivity_); } |
6a17a36d FC |
36 | private: |
37 | SBuf prefix_; | |
514fc315 | 38 | SBufCaseSensitive sensitivity_; |
6a17a36d FC |
39 | }; |
40 | ||
41 | /** SBuf size addition accumulator for STL contaniners | |
42 | * | |
43 | * Equivalent to prefix_length + SBuf.length() + separator.length() | |
44 | */ | |
514fc315 FC |
45 | class SBufAddLength |
46 | { | |
6a17a36d FC |
47 | public: |
48 | explicit SBufAddLength(const SBuf &separator) : | |
86c63190 | 49 | separatorLen_(separator.length()) {} |
6a17a36d | 50 | SBuf::size_type operator()(const SBuf::size_type sz, const SBuf & item) { |
2d2e4881 | 51 | return sz + item.length() + separatorLen_; |
6a17a36d FC |
52 | } |
53 | private: | |
2d2e4881 | 54 | SBuf::size_type separatorLen_; |
6a17a36d FC |
55 | }; |
56 | ||
57 | /// join all the SBuf in a container of SBuf into a single SBuf, separating with separator | |
58 | template <class Container> | |
59 | SBuf | |
60 | SBufContainerJoin(const Container &items, const SBuf& separator) | |
61 | { | |
62 | // optimization: pre-calculate needed storage | |
514fc315 | 63 | const SBuf::size_type sz = std::accumulate(items.begin(), items.end(), 0, SBufAddLength(separator)); |
6a17a36d | 64 | |
2d2e4881 FC |
65 | // sz can be zero in two cases: either items is empty, or all items |
66 | // are zero-length. In the former case, we must protect against | |
67 | // dereferencing the iterator later on, and checking sz is more efficient | |
68 | // than checking items.size(). This check also provides an optimization | |
69 | // for the latter case without adding complexity. | |
6a17a36d FC |
70 | if (sz == 0) |
71 | return SBuf(); | |
72 | ||
73 | SBuf rv; | |
74 | rv.reserveSpace(sz); | |
75 | ||
76 | typename Container::const_iterator i(items.begin()); | |
77 | rv.append(*i); | |
78 | ++i; | |
86c63190 | 79 | for (; i != items.end(); ++i) |
6a17a36d FC |
80 | rv.append(separator).append(*i); |
81 | return rv; | |
82 | } | |
83 | ||
84 | #endif /* SQUID_SBUFALGOS_H_ */ |