diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index fa5fb8082..121b5756a 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -232,6 +232,39 @@ std::set keys(std::map const& _map) return applyMap(_map, [](auto const& _elem) { return _elem.first; }, std::set{}); } +/// @returns a pointer to the entry of @a _map at @a _key, if there is one, and nullptr otherwise. +template +decltype(auto) valueOrNullptr(MapType&& _map, KeyType const& _key) +{ + auto it = _map.find(_key); + return (it == _map.end()) ? nullptr : &it->second; +} + +namespace detail +{ +struct allow_copy {}; +} +static constexpr auto allow_copy = detail::allow_copy{}; + +/// @returns a reference to the entry of @a _map at @a _key, if there is one, and @a _defaultValue otherwise. +/// Makes sure no copy is involved, unless allow_copy is passed as fourth argument. +template< + typename MapType, + typename KeyType, + typename ValueType = std::decay_t().find(std::declval())->second)> const&, + typename AllowCopyType = void* +> +decltype(auto) valueOrDefault(MapType&& _map, KeyType const& _key, ValueType&& _defaultValue = {}, AllowCopyType = nullptr) +{ + auto it = _map.find(_key); + static_assert( + std::is_same_v || + std::is_reference_vsecond)>, + "valueOrDefault does not allow copies by default. Pass allow_copy as additional argument, if you want to allow copies." + ); + return (it == _map.end()) ? _defaultValue : it->second; +} + // String conversion functions, mainly to/from hex/nibble/byte representations. enum class WhenError