util.hh: Move stuff to types.hh
Change-Id: Ia852306a4b8aac6856dc42bc69e4b58b53a0d67c
This commit is contained in:
parent
74513483bc
commit
d73c40ff3d
2 changed files with 111 additions and 108 deletions
|
@ -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.
|
||||
|
|
|
@ -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...>;
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue