• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.95
/src/lib/utils/stl_util.h
1
/*
2
* STL Utility Functions
3
* (C) 1999-2007 Jack Lloyd
4
* (C) 2015 Simon Warta (Kullo GmbH)
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#ifndef BOTAN_STL_UTIL_H_
10
#define BOTAN_STL_UTIL_H_
11

12
#include <map>
13
#include <set>
14
#include <span>
15
#include <string>
16
#include <tuple>
17
#include <variant>
18
#include <vector>
19

20
#include <botan/concepts.h>
21
#include <botan/secmem.h>
22
#include <botan/strong_type.h>
23

24
namespace Botan {
25

26
inline std::vector<uint8_t> to_byte_vector(std::string_view s) {
631✔
27
   return std::vector<uint8_t>(s.cbegin(), s.cend());
631✔
28
}
29

30
inline std::string to_string(const secure_vector<uint8_t>& bytes) {
31
   return std::string(bytes.cbegin(), bytes.cend());
32
}
33

34
/**
35
* Return the keys of a map as a std::set
36
*/
37
template <typename K, typename V>
38
std::set<K> map_keys_as_set(const std::map<K, V>& kv) {
×
39
   std::set<K> s;
×
40
   for(auto&& i : kv) {
×
41
      s.insert(i.first);
×
42
   }
43
   return s;
×
44
}
×
45

46
/**
47
* Return the keys of a multimap as a std::set
48
*/
49
template <typename K, typename V>
50
std::set<K> map_keys_as_set(const std::multimap<K, V>& kv) {
×
51
   std::set<K> s;
×
52
   for(auto&& i : kv) {
×
53
      s.insert(i.first);
×
54
   }
55
   return s;
×
56
}
×
57

58
/*
59
* Searching through a std::map
60
* @param mapping the map to search
61
* @param key is what to look for
62
* @param null_result is the value to return if key is not in mapping
63
* @return mapping[key] or null_result
64
*/
65
template <typename K, typename V>
66
inline V search_map(const std::map<K, V>& mapping, const K& key, const V& null_result = V()) {
17✔
67
   auto i = mapping.find(key);
17✔
68
   if(i == mapping.end())
17✔
69
      return null_result;
17✔
70
   return i->second;
16✔
71
}
72

73
template <typename K, typename V, typename R>
74
inline R search_map(const std::map<K, V>& mapping, const K& key, const R& null_result, const R& found_result) {
75
   auto i = mapping.find(key);
76
   if(i == mapping.end())
77
      return null_result;
78
   return found_result;
79
}
80

81
/*
82
* Insert a key/value pair into a multimap
83
*/
84
template <typename K, typename V>
85
void multimap_insert(std::multimap<K, V>& multimap, const K& key, const V& value) {
591,903✔
86
   multimap.insert(std::make_pair(key, value));
591,903✔
87
}
591,903✔
88

89
/**
90
* Existence check for values
91
*/
92
template <typename T, typename OT>
93
bool value_exists(const std::vector<T>& vec, const OT& val) {
189,772✔
94
   for(size_t i = 0; i != vec.size(); ++i)
675,181✔
95
      if(vec[i] == val)
659,501✔
96
         return true;
97,426✔
97
   return false;
98
}
99

100
template <typename T, typename Pred>
101
void map_remove_if(Pred pred, T& assoc) {
2,048✔
102
   auto i = assoc.begin();
2,048✔
103
   while(i != assoc.end()) {
2,048✔
104
      if(pred(i->first))
4,096✔
105
         assoc.erase(i++);
2,048✔
106
      else
107
         i++;
6,144✔
108
   }
109
}
2,048✔
110

111
/**
112
 * Helper class to ease unmarshalling of concatenated fixed-length values
113
 */
114
class BufferSlicer final {
115
   public:
116
      BufferSlicer(std::span<const uint8_t> buffer) : m_remaining(buffer) {}
2,652✔
117

118
      template <concepts::contiguous_container ContainerT>
119
      auto copy(const size_t count) {
3,329✔
120
         const auto result = take(count);
3,329✔
121
         return ContainerT(result.begin(), result.end());
3,327✔
122
      }
123

124
      auto copy_as_vector(const size_t count) { return copy<std::vector<uint8_t>>(count); }
769✔
125

126
      auto copy_as_secure_vector(const size_t count) { return copy<secure_vector<uint8_t>>(count); }
1,264✔
127

128
      std::span<const uint8_t> take(const size_t count) {
6,316✔
129
         BOTAN_STATE_CHECK(remaining() >= count);
6✔
130
         auto result = m_remaining.first(count);
6,310✔
131
         m_remaining = m_remaining.subspan(count);
6,310✔
132
         return result;
6,310✔
133
      }
134

135
      template <concepts::contiguous_strong_type T>
136
      StrongSpan<const T> take(const size_t count) {
1✔
137
         return StrongSpan<const T>(take(count));
1✔
138
      }
139

140
      void copy_into(std::span<uint8_t> sink) {
2✔
141
         const auto data = take(sink.size());
2✔
142
         std::copy(data.begin(), data.end(), sink.begin());
2✔
143
      }
2✔
144

145
      void skip(const size_t count) { take(count); }
593✔
146

147
      size_t remaining() const { return m_remaining.size(); }
7,618✔
148

149
      bool empty() const { return m_remaining.empty(); }
842✔
150

151
   private:
152
      std::span<const uint8_t> m_remaining;
153
};
154

155
/**
156
 * @brief Helper class to ease in-place marshalling of concatenated fixed-length
157
 *        values.
158
 *
159
 * The size of the final buffer must be known from the start, reallocations are
160
 * not performed.
161
 */
162
class BufferStuffer {
163
   public:
164
      BufferStuffer(std::span<uint8_t> buffer) : m_buffer(buffer) {}
1✔
165

166
      /**
167
       * @returns a span for the next @p bytes bytes in the concatenated buffer.
168
       *          Checks that the buffer is not exceded.
169
       */
170
      std::span<uint8_t> next(size_t bytes) {
8✔
171
         BOTAN_STATE_CHECK(m_buffer.size() >= bytes);
8✔
172

173
         auto result = m_buffer.first(bytes);
4✔
174
         m_buffer = m_buffer.subspan(bytes);
4✔
175
         return result;
4✔
176
      }
177

178
      template <concepts::contiguous_strong_type StrongT>
179
      StrongSpan<StrongT> next(size_t bytes) {
1✔
180
         return StrongSpan<StrongT>(next(bytes));
1✔
181
      }
182

183
      void append(std::span<const uint8_t> buffer) {
3✔
184
         auto sink = next(buffer.size());
3✔
185
         std::copy(buffer.begin(), buffer.end(), sink.begin());
1✔
186
      }
1✔
187

188
      bool full() const { return m_buffer.empty(); }
3✔
189

190
      size_t remaining_capacity() const { return m_buffer.size(); }
4✔
191

192
   private:
193
      std::span<uint8_t> m_buffer;
194
};
195

196
/**
197
 * Concatenate an arbitrary number of buffers.
198
 * @return the concatenation of \p buffers as the container type of the first buffer
199
 */
200
template <typename... Ts>
201
decltype(auto) concat(Ts&&... buffers) {
3,525,316✔
202
   static_assert(sizeof...(buffers) > 0, "concat requires at least one buffer");
203

204
   using result_t = std::remove_cvref_t<std::tuple_element_t<0, std::tuple<Ts...>>>;
205
   result_t result;
3,525,316✔
206
   result.reserve((buffers.size() + ...));
3,525,316✔
207
   (result.insert(result.end(), buffers.begin(), buffers.end()), ...);
3,525,316✔
208
   return result;
3,525,316✔
209
}
×
210

211
/**
212
 * Concatenate an arbitrary number of buffers and define the output buffer
213
 * type as a mandatory template parameter.
214
 * @return the concatenation of \p buffers as the user-defined container type
215
 */
216
template <typename ResultT, typename... Ts>
217
ResultT concat_as(Ts&&... buffers) {
3,519,411✔
218
   return concat(ResultT(), std::forward<Ts>(buffers)...);
7,038,822✔
219
}
220

221
template <typename... Alts, typename... Ts>
222
constexpr bool holds_any_of(const std::variant<Ts...>& v) noexcept {
3,624✔
223
   return (std::holds_alternative<Alts>(v) || ...);
3,624✔
224
}
225

226
template <typename GeneralVariantT, typename SpecialT>
227
constexpr bool is_generalizable_to(const SpecialT&) noexcept {
228
   return std::is_constructible_v<GeneralVariantT, SpecialT>;
229
}
230

231
template <typename GeneralVariantT, typename... SpecialTs>
232
constexpr bool is_generalizable_to(const std::variant<SpecialTs...>&) noexcept {
233
   return (std::is_constructible_v<GeneralVariantT, SpecialTs> && ...);
234
}
235

236
/**
237
 * @brief Converts a given variant into another variant-ish whose type states
238
 *        are a super set of the given variant.
239
 *
240
 * This is useful to convert restricted variant types into more general
241
 * variants types.
242
 */
243
template <typename GeneralVariantT, typename SpecialT>
244
constexpr GeneralVariantT generalize_to(SpecialT&& specific) noexcept
1,369✔
245
   requires(std::is_constructible_v<GeneralVariantT, std::decay_t<SpecialT>>)
246
{
247
   return std::forward<SpecialT>(specific);
1,369✔
248
}
249

250
/**
251
 * @brief Converts a given variant into another variant-ish whose type states
252
 *        are a super set of the given variant.
253
 *
254
 * This is useful to convert restricted variant types into more general
255
 * variants types.
256
 */
257
template <typename GeneralVariantT, typename... SpecialTs>
258
constexpr GeneralVariantT generalize_to(std::variant<SpecialTs...> specific) noexcept {
3,226✔
259
   static_assert(
260
      is_generalizable_to<GeneralVariantT>(specific),
261
      "Desired general type must be implicitly constructible by all types of the specialized std::variant<>");
262
   return std::visit([](auto s) -> GeneralVariantT { return s; }, std::move(specific));
5,083✔
263
}
264

265
// This is a helper utility to emulate pattern matching with std::visit.
266
// See https://en.cppreference.com/w/cpp/utility/variant/visit for more info.
267
template <class... Ts>
268
struct overloaded : Ts... {
269
      using Ts::operator()...;
270
};
271
// explicit deduction guide (not needed as of C++20)
272
template <class... Ts>
273
overloaded(Ts...) -> overloaded<Ts...>;
274

275
}  // namespace Botan
276

277
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc