]> git.ipfire.org Git - thirdparty/squid.git/blob - src/sbuf/Algorithms.h
renamed sbuf/SBufAlgos.h to sbuf/Algorithms.h
[thirdparty/squid.git] / src / sbuf / Algorithms.h
1 /*
2 * Copyright (C) 1996-2016 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
9 #ifndef SQUID_SBUFALGOS_H_
10 #define SQUID_SBUFALGOS_H_
11
12 #include "SBuf.h"
13
14 #include <algorithm>
15 #include <numeric>
16
17 /// SBuf equality predicate for STL algorithms etc
18 class SBufEqual
19 {
20 public:
21 explicit SBufEqual(const SBuf &reference, SBufCaseSensitive sensitivity = caseSensitive) :
22 reference_(reference), sensitivity_(sensitivity) {}
23 bool operator() (const SBuf & checking) { return checking.compare(reference_,sensitivity_) == 0; }
24 private:
25 SBuf reference_;
26 SBufCaseSensitive sensitivity_;
27 };
28
29 /// SBuf "starts with" predicate for STL algorithms etc
30 class SBufStartsWith
31 {
32 public:
33 explicit SBufStartsWith(const SBuf &prefix, SBufCaseSensitive sensitivity = caseSensitive) :
34 prefix_(prefix), sensitivity_(sensitivity) {}
35 bool operator() (const SBuf & checking) { return checking.startsWith(prefix_,sensitivity_); }
36 private:
37 SBuf prefix_;
38 SBufCaseSensitive sensitivity_;
39 };
40
41 /** SBuf size addition accumulator for STL contaniners
42 *
43 * Equivalent to prefix_length + SBuf.length() + separator.length()
44 */
45 class SBufAddLength
46 {
47 public:
48 explicit SBufAddLength(const SBuf &separator) :
49 separatorLen_(separator.length()) {}
50 SBuf::size_type operator()(const SBuf::size_type sz, const SBuf & item) {
51 return sz + item.length() + separatorLen_;
52 }
53 private:
54 SBuf::size_type separatorLen_;
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
63 const SBuf::size_type sz = std::accumulate(items.begin(), items.end(), 0, SBufAddLength(separator));
64
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.
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;
79 for (; i != items.end(); ++i)
80 rv.append(separator).append(*i);
81 return rv;
82 }
83
84 namespace std {
85 /// default hash functor to support std::unordered_map<SBuf,*>
86 template <>
87 struct hash<SBuf>
88 {
89 size_t operator()(const SBuf &) const noexcept;
90 };
91 }
92
93 /** hash functor for SBufs, meant so support case-insensitive std::unordered_map
94 *
95 * Typical use:
96 * \code
97 * auto m = std::unordered_map<SBuf, ValueType, CaseInsensitiveSBufHash>();
98 * \endcode
99 */
100 class CaseInsensitiveSBufHash
101 {
102 public:
103 std::size_t operator()(const SBuf &) const noexcept;
104 };
105
106 #endif /* SQUID_SBUFALGOS_H_ */
107