Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
util.hh
Go to the documentation of this file.
1#pragma once
3
4#include "types.hh"
5#include "error.hh"
6#include "logging.hh"
7
8
9#include <functional>
10#include <map>
11#include <sstream>
12#include <optional>
13
14#include "strings.hh"
15
16namespace nix {
17
18void initLibUtil();
19
25std::vector<char *> stringsToCharPtrs(const Strings & ss);
26
27
28MakeError(FormatError, Error);
29
30
31template<class... Parts>
32auto concatStrings(Parts &&... parts)
33 -> std::enable_if_t<(... && std::is_convertible_v<Parts, std::string_view>), std::string>
34{
35 std::string_view views[sizeof...(parts)] = {parts...};
36 return concatStringsSep({}, views);
37}
38
39
43template<class C> Strings quoteStrings(const C & c)
44{
45 Strings res;
46 for (auto & s : c)
47 res.push_back("'" + s + "'");
48 return res;
49}
50
56std::string chomp(std::string_view s);
57
58
62std::string trim(std::string_view s, std::string_view whitespace = " \n\r\t");
63
64
68std::string replaceStrings(
69 std::string s,
70 std::string_view from,
71 std::string_view to);
72
73
74std::string rewriteStrings(std::string s, const StringMap & rewrites);
75
76
80template<class N>
81std::optional<N> string2Int(const std::string_view s);
82
87template<class N>
88N string2IntWithUnitPrefix(std::string_view s)
89{
90 uint64_t multiplier = 1;
91 if (!s.empty()) {
92 char u = std::toupper(*s.rbegin());
93 if (std::isalpha(u)) {
94 if (u == 'K') multiplier = 1ULL << 10;
95 else if (u == 'M') multiplier = 1ULL << 20;
96 else if (u == 'G') multiplier = 1ULL << 30;
97 else if (u == 'T') multiplier = 1ULL << 40;
98 else throw UsageError("invalid unit specifier '%1%'", u);
99 s.remove_suffix(1);
100 }
101 }
102 if (auto n = string2Int<N>(s))
103 return *n * multiplier;
104 throw UsageError("'%s' is not an integer", s);
105}
106
112std::string renderSize(uint64_t value, bool align = false);
113
117template<class N>
118std::optional<N> string2Float(const std::string_view s);
119
120
124template<typename T>
125T readLittleEndian(unsigned char * p)
126{
127 T x = 0;
128 for (size_t i = 0; i < sizeof(x); ++i, ++p) {
129 x |= ((T) *p) << (i * 8);
130 }
131 return x;
132}
133
134
138bool hasPrefix(std::string_view s, std::string_view prefix);
139
140
144bool hasSuffix(std::string_view s, std::string_view suffix);
145
146
150std::string toLower(std::string s);
151
152
156std::string shellEscape(const std::string_view s);
157
158
169void ignoreExceptionInDestructor(Verbosity lvl = lvlError);
170
178void ignoreExceptionExceptInterrupt(Verbosity lvl = lvlError);
179
180
181
185constexpr char treeConn[] = "├───";
186constexpr char treeLast[] = "└───";
187constexpr char treeLine[] = "│ ";
188constexpr char treeNull[] = " ";
189
190
194std::string base64Encode(std::string_view s);
195
199std::string base64Decode(std::string_view s);
200
201
207std::string stripIndentation(std::string_view s);
208
209
215std::pair<std::string_view, std::string_view> getLine(std::string_view s);
216
217
221template <class T>
222const typename T::mapped_type * get(const T & map, const typename T::key_type & key)
223{
224 auto i = map.find(key);
225 if (i == map.end()) return nullptr;
226 return &i->second;
227}
228
229template <class T>
230typename T::mapped_type * get(T & map, const typename T::key_type & key)
231{
232 auto i = map.find(key);
233 if (i == map.end()) return nullptr;
234 return &i->second;
235}
236
240template <class T>
241const typename T::mapped_type & getOr(T & map,
242 const typename T::key_type & key,
243 const typename T::mapped_type & defaultValue)
244{
245 auto i = map.find(key);
246 if (i == map.end()) return defaultValue;
247 return i->second;
248}
249
253template <class T>
254std::optional<typename T::value_type> remove_begin(T & c)
255{
256 auto i = c.begin();
257 if (i == c.end()) return {};
258 auto v = std::move(*i);
259 c.erase(i);
260 return v;
261}
262
263
267template <class T>
268std::optional<typename T::value_type> pop(T & c)
269{
270 if (c.empty()) return {};
271 auto v = std::move(c.front());
272 c.pop();
273 return v;
274}
275
276
281template<class C, typename T>
282void append(C & c, std::initializer_list<T> l)
283{
284 c.insert(c.end(), l.begin(), l.end());
285}
286
287
288template<typename T>
289class Callback;
290
291
296template<typename T>
297struct MaintainCount
298{
299 T & counter;
300 long delta;
301 MaintainCount(T & counter, long delta = 1) : counter(counter), delta(delta) { counter += delta; }
302 ~MaintainCount() { counter -= delta; }
303};
304
305
311template <typename T,
312 typename TIter = decltype(std::begin(std::declval<T>())),
313 typename = decltype(std::end(std::declval<T>()))>
314constexpr auto enumerate(T && iterable)
315{
316 struct iterator
317 {
318 size_t i;
319 TIter iter;
320 constexpr bool operator != (const iterator & other) const { return iter != other.iter; }
321 constexpr void operator ++ () { ++i; ++iter; }
322 constexpr auto operator * () const { return std::tie(i, *iter); }
323 };
324
325 struct iterable_wrapper
326 {
327 T iterable;
328 constexpr auto begin() { return iterator{ 0, std::begin(iterable) }; }
329 constexpr auto end() { return iterator{ 0, std::end(iterable) }; }
330 };
331
332 return iterable_wrapper{ std::forward<T>(iterable) };
333}
334
335
339template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
340template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
341
342
343std::string showBytes(uint64_t bytes);
344
345
350inline std::string operator + (const std::string & s1, std::string_view s2)
351{
352 std::string s;
353 s.reserve(s1.size() + s2.size());
354 s.append(s1);
355 s.append(s2);
356 return s;
357}
358
359inline std::string operator + (std::string && s, std::string_view s2)
360{
361 s.append(s2);
362 return std::move(s);
363}
364
365inline std::string operator + (std::string_view s1, const char * s2)
366{
367 auto s2Size = strlen(s2);
368 std::string s;
369 s.reserve(s1.size() + s2Size);
370 s.append(s1);
371 s.append(s2, s2Size);
372 return s;
373}
374
375}
This file defines two main structs/classes used in nix error handling.
PosIdx end
Definition lexer.l:5814
Consider removing the empty string dropping behavior If use concatStringsSep instead std::string std::enable_if_t<(... &&std::is_convertible_v< Parts, std::string_view >), std::string > std::string_view views[sizeof...(parts)]
Definition lexer.l:2556
const T::key_type & key
Definition lexer.l:2763
auto i
Definition lexer.l:2745
return s
Definition lexer.l:459
Strings res
Definition lexer.l:2566
T x
Definition lexer.l:2648
std::shared_ptr< T > p
Definition lexer.l:1269
std::string std::string_view from
Definition lexer.l:2591
PosIdx begin
Definition lexer.l:5809
uint64_t multiplier
Definition lexer.l:2611
void pop()
const T & value
Definition lexer.l:492
TIter
Definition lexer.l:2833
std::string std::string_view std::string_view to
Definition lexer.l:2592
Definition lexer.l:2847
Definition util.hh:339
std::optional< typename T::value_type > remove_begin(T &c)
Definition util.hh:254
constexpr auto enumerate(T &&iterable)
Definition util.hh:314
T readLittleEndian(unsigned char *p)
Definition util.hh:125
N string2IntWithUnitPrefix(std::string_view s)
Definition util.hh:88
constexpr char treeConn[]
Definition util.hh:185
const T::mapped_type & getOr(T &map, const typename T::key_type &key, const typename T::mapped_type &defaultValue)
Definition util.hh:241
Strings quoteStrings(const C &c)
Definition util.hh:43