]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
bbc27441 AJ |
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 | ||
517fc64c | 12 | #include "sbuf/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) : |
f53969cc | 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) : |
f53969cc | 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) : | |
f53969cc | 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 | ||
f9879a34 FC |
57 | /** Join container of SBufs and append to supplied target |
58 | * | |
59 | * append to the target SBuf all elements in the [begin,end) range from | |
60 | * an iterable container, prefixed by prefix, separated by separator and | |
61 | * followed by suffix. Prefix and suffix are added also in case of empty | |
62 | * iterable | |
63 | * | |
64 | * \return the modified dest | |
65 | */ | |
66 | template <class ContainerIterator> | |
67 | SBuf& | |
68 | JoinContainerIntoSBuf(SBuf &dest, const ContainerIterator &begin, | |
80bd33c3 SM |
69 | const ContainerIterator &end, const SBuf& separator, |
70 | const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf()) | |
6a17a36d | 71 | { |
f9879a34 | 72 | if (begin == end) { |
80bd33c3 | 73 | dest.append(prefix).append(suffix); |
f9879a34 FC |
74 | return dest; |
75 | } | |
6a17a36d | 76 | |
f9879a34 FC |
77 | // optimization: pre-calculate needed storage |
78 | const SBuf::size_type totalContainerSize = | |
80bd33c3 SM |
79 | std::accumulate(begin, end, 0, SBufAddLength(separator)) + |
80 | dest.length() + prefix.length() + suffix.length(); | |
f9879a34 FC |
81 | SBufReservationRequirements req; |
82 | req.minSpace = totalContainerSize; | |
83 | dest.reserve(req); | |
6a17a36d | 84 | |
f9879a34 FC |
85 | auto i = begin; |
86 | dest.append(prefix); | |
87 | dest.append(*i); | |
6a17a36d | 88 | ++i; |
f9879a34 FC |
89 | for (; i != end; ++i) |
90 | dest.append(separator).append(*i); | |
91 | dest.append(suffix); | |
92 | return dest; | |
93 | } | |
94 | ||
95 | /// convenience wrapper of JoinContainerIntoSBuf with no caller-supplied SBuf | |
96 | template <class ContainerIterator> | |
97 | SBuf | |
98 | JoinContainerToSBuf(const ContainerIterator &begin, | |
80bd33c3 SM |
99 | const ContainerIterator &end, const SBuf& separator, |
100 | const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf()) | |
f9879a34 | 101 | { |
80bd33c3 SM |
102 | SBuf rv; |
103 | return JoinContainerIntoSBuf(rv, begin, end, separator, prefix, suffix); | |
6a17a36d FC |
104 | } |
105 | ||
25436c30 | 106 | namespace std { |
132d9943 SM |
107 | /// default hash functor to support std::unordered_map<SBuf,*> |
108 | template <> | |
109 | struct hash<SBuf> | |
110 | { | |
111 | size_t operator()(const SBuf &) const noexcept; | |
112 | }; | |
25436c30 FC |
113 | } |
114 | ||
ae72213d FC |
115 | /** hash functor for SBufs, meant so support case-insensitive std::unordered_map |
116 | * | |
117 | * Typical use: | |
118 | * \code | |
119 | * auto m = std::unordered_map<SBuf, ValueType, CaseInsensitiveSBufHash>(); | |
120 | * \endcode | |
121 | */ | |
122 | class CaseInsensitiveSBufHash | |
123 | { | |
124 | public: | |
125 | std::size_t operator()(const SBuf &) const noexcept; | |
126 | }; | |
127 | ||
6a17a36d | 128 | #endif /* SQUID_SBUFALGOS_H_ */ |
f53969cc | 129 |