diff options
author | Tom Hubrecht <github@mail.hubrecht.ovh> | 2024-05-28 16:24:19 +0200 |
---|---|---|
committer | Tom Hubrecht <github@mail.hubrecht.ovh> | 2024-05-29 11:42:42 +0200 |
commit | d73c40ff3d74e9b1bac24c104fdf7738df3c3029 (patch) | |
tree | add7e97611392a5f63f62dbfe7077db417ffa45c /src/libutil | |
parent | 74513483bc5572d988a059b8e964662d66f1667f (diff) |
util.hh: Move stuff to types.hh
Change-Id: Ia852306a4b8aac6856dc42bc69e4b58b53a0d67c
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/types.hh | 111 | ||||
-rw-r--r-- | src/libutil/util.hh | 108 |
2 files changed, 111 insertions, 108 deletions
diff --git a/src/libutil/types.hh b/src/libutil/types.hh index c86f52175..4974634d8 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -4,6 +4,7 @@ #include "ref.hh" #include <list> +#include <optional> #include <set> #include <string> #include <limits> @@ -51,6 +52,116 @@ struct Explicit { } }; +/** + * Get a value for the specified key from an associate container. + */ +template <class T> +const typename T::mapped_type * get(const T & map, const typename T::key_type & key) +{ + auto i = map.find(key); + if (i == map.end()) return nullptr; + return &i->second; +} + +template <class T> +typename T::mapped_type * get(T & map, const typename T::key_type & key) +{ + auto i = map.find(key); + if (i == map.end()) return nullptr; + return &i->second; +} + +/** + * Get a value for the specified key from an associate container, or a default value if the key isn't present. + */ +template <class T> +const typename T::mapped_type & getOr(T & map, + const typename T::key_type & key, + const typename T::mapped_type & defaultValue) +{ + auto i = map.find(key); + if (i == map.end()) return defaultValue; + return i->second; +} + +/** + * Remove and return the first item from a container. + */ +template <class T> +std::optional<typename T::value_type> remove_begin(T & c) +{ + auto i = c.begin(); + if (i == c.end()) return {}; + auto v = std::move(*i); + c.erase(i); + return v; +} + + +/** + * Remove and return the first item from a container. + */ +template <class T> +std::optional<typename T::value_type> pop(T & c) +{ + if (c.empty()) return {}; + auto v = std::move(c.front()); + c.pop(); + return v; +} + + +/** + * A RAII helper that increments a counter on construction and + * decrements it on destruction. + */ +template<typename T> +struct MaintainCount +{ + T & counter; + long delta; + MaintainCount(T & counter, long delta = 1) : counter(counter), delta(delta) { counter += delta; } + ~MaintainCount() { counter -= delta; } +}; + + +/** + * A Rust/Python-like enumerate() iterator adapter. + * + * Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17. + */ +template <typename T, + typename TIter = decltype(std::begin(std::declval<T>())), + typename = decltype(std::end(std::declval<T>()))> +constexpr auto enumerate(T && iterable) +{ + struct iterator + { + size_t i; + TIter iter; + constexpr bool operator != (const iterator & other) const { return iter != other.iter; } + constexpr void operator ++ () { ++i; ++iter; } + constexpr auto operator * () const { return std::tie(i, *iter); } + }; + + struct iterable_wrapper + { + T iterable; + constexpr auto begin() { return iterator{ 0, std::begin(iterable) }; } + constexpr auto end() { return iterator{ 0, std::end(iterable) }; } + }; + + return iterable_wrapper{ std::forward<T>(iterable) }; +} + + +/** + * C++17 std::visit boilerplate + */ +template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; +template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; + + /** * This wants to be a little bit like rust's Cow type. diff --git a/src/libutil/util.hh b/src/libutil/util.hh index c5ca12650..4e20550a7 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -40,114 +40,6 @@ extern const std::string nativeSystem; -/** - * Get a value for the specified key from an associate container. - */ -template <class T> -const typename T::mapped_type * get(const T & map, const typename T::key_type & key) -{ - auto i = map.find(key); - if (i == map.end()) return nullptr; - return &i->second; -} - -template <class T> -typename T::mapped_type * get(T & map, const typename T::key_type & key) -{ - auto i = map.find(key); - if (i == map.end()) return nullptr; - return &i->second; -} - -/** - * Get a value for the specified key from an associate container, or a default value if the key isn't present. - */ -template <class T> -const typename T::mapped_type & getOr(T & map, - const typename T::key_type & key, - const typename T::mapped_type & defaultValue) -{ - auto i = map.find(key); - if (i == map.end()) return defaultValue; - return i->second; -} - -/** - * Remove and return the first item from a container. - */ -template <class T> -std::optional<typename T::value_type> remove_begin(T & c) -{ - auto i = c.begin(); - if (i == c.end()) return {}; - auto v = std::move(*i); - c.erase(i); - return v; -} - - -/** - * Remove and return the first item from a container. - */ -template <class T> -std::optional<typename T::value_type> pop(T & c) -{ - if (c.empty()) return {}; - auto v = std::move(c.front()); - c.pop(); - return v; -} - - -/** - * A RAII helper that increments a counter on construction and - * decrements it on destruction. - */ -template<typename T> -struct MaintainCount -{ - T & counter; - long delta; - MaintainCount(T & counter, long delta = 1) : counter(counter), delta(delta) { counter += delta; } - ~MaintainCount() { counter -= delta; } -}; - - -/** - * A Rust/Python-like enumerate() iterator adapter. - * - * Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17. - */ -template <typename T, - typename TIter = decltype(std::begin(std::declval<T>())), - typename = decltype(std::end(std::declval<T>()))> -constexpr auto enumerate(T && iterable) -{ - struct iterator - { - size_t i; - TIter iter; - constexpr bool operator != (const iterator & other) const { return iter != other.iter; } - constexpr void operator ++ () { ++i; ++iter; } - constexpr auto operator * () const { return std::tie(i, *iter); } - }; - - struct iterable_wrapper - { - T iterable; - constexpr auto begin() { return iterator{ 0, std::begin(iterable) }; } - constexpr auto end() { return iterator{ 0, std::end(iterable) }; } - }; - - return iterable_wrapper{ std::forward<T>(iterable) }; -} - - -/** - * C++17 std::visit boilerplate - */ -template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; -template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; } |