2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_SBUF_ALGORITHMS_H
10 #define SQUID_SRC_SBUF_ALGORITHMS_H
12 #include "sbuf/SBuf.h"
17 /// SBuf equality predicate for STL algorithms etc
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; }
26 SBufCaseSensitive sensitivity_
;
29 /// SBuf "starts with" predicate for STL algorithms etc
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_
); }
38 SBufCaseSensitive sensitivity_
;
41 /** SBuf size addition accumulator for STL contaniners
43 * Equivalent to prefix_length + SBuf.length() + separator.length()
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_
;
54 SBuf::size_type separatorLen_
;
57 /** Join container of SBufs and append to supplied target
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
64 * \return the modified dest
66 template <class ContainerIterator
>
68 JoinContainerIntoSBuf(SBuf
&dest
, const ContainerIterator
&begin
,
69 const ContainerIterator
&end
, const SBuf
& separator
,
70 const SBuf
& prefix
= SBuf(), const SBuf
& suffix
= SBuf())
73 dest
.append(prefix
).append(suffix
);
77 // optimization: pre-calculate needed storage
78 const SBuf::size_type totalContainerSize
=
79 std::accumulate(begin
, end
, 0, SBufAddLength(separator
)) +
80 dest
.length() + prefix
.length() + suffix
.length();
81 SBufReservationRequirements req
;
82 req
.minSpace
= totalContainerSize
;
90 dest
.append(separator
).append(*i
);
95 /// convenience wrapper of JoinContainerIntoSBuf with no caller-supplied SBuf
96 template <class ContainerIterator
>
98 JoinContainerToSBuf(const ContainerIterator
&begin
,
99 const ContainerIterator
&end
, const SBuf
& separator
,
100 const SBuf
& prefix
= SBuf(), const SBuf
& suffix
= SBuf())
103 return JoinContainerIntoSBuf(rv
, begin
, end
, separator
, prefix
, suffix
);
107 /// default hash functor to support std::unordered_map<SBuf,*>
111 size_t operator()(const SBuf
&) const noexcept
;
115 /// hash functor for case-insensitive SBufs
116 /// \sa std::hash<SBuf>
117 class CaseInsensitiveSBufHash
120 std::size_t operator()(const SBuf
&) const noexcept
;
123 /// equality functor for case-insensitive SBufs
124 /// \sa std::equal_to<SBuf>
125 class CaseInsensitiveSBufEqual
128 bool operator()(const SBuf
&lhs
, const SBuf
&rhs
) const
130 // Optimization: Do not iterate strings of different lengths.
131 return lhs
.length() == rhs
.length() && (lhs
.compare(rhs
, caseInsensitive
) == 0);
135 #endif /* SQUID_SRC_SBUF_ALGORITHMS_H */