From f3e3f758381f9e55c2125cb6d4e862cd84f14a02 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 15 Sep 2025 12:25:37 -0400 Subject: [PATCH] More `get` / `getOr` improvements - Use `const K`, not `K`, otherwise we don't get auto referencing of rvalues. - Generalized the deleted overloads, because we don't care what the key type is --- we want to get rid of anything that has an rvalue map type. --- src/libutil/include/nix/util/util.hh | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libutil/include/nix/util/util.hh b/src/libutil/include/nix/util/util.hh index 561550c41..2e78120fc 100644 --- a/src/libutil/include/nix/util/util.hh +++ b/src/libutil/include/nix/util/util.hh @@ -197,7 +197,7 @@ std::pair getLine(std::string_view s); * Get a value for the specified key from an associate container. */ template -const typename T::mapped_type * get(const T & map, K & key) +const typename T::mapped_type * get(const T & map, const K & key) { auto i = map.find(key); if (i == map.end()) @@ -206,7 +206,7 @@ const typename T::mapped_type * get(const T & map, K & key) } template -typename T::mapped_type * get(T & map, K & key) +typename T::mapped_type * get(T & map, const K & key) { auto i = map.find(key); if (i == map.end()) @@ -214,15 +214,17 @@ typename T::mapped_type * get(T & map, K & key) return &i->second; } -/** Deleted because this is use-after-free liability. Just don't pass temporaries to this overload set. */ -template -typename T::mapped_type * get(T && map, const typename T::key_type & key) = delete; +/** + * Deleted because this is use-after-free liability. Just don't pass temporaries to this overload set. + */ +template +typename T::mapped_type * get(T && map, const K & key) = delete; /** * Get a value for the specified key from an associate container, or a default value if the key isn't present. */ template -const typename T::mapped_type & getOr(T & map, K & key, const typename T::mapped_type & defaultValue) +const typename T::mapped_type & getOr(T & map, const K & key, const typename T::mapped_type & defaultValue) { auto i = map.find(key); if (i == map.end()) @@ -230,10 +232,11 @@ const typename T::mapped_type & getOr(T & map, K & key, const typename T::mapped return i->second; } -/** Deleted because this is use-after-free liability. Just don't pass temporaries to this overload set. */ -template -const typename T::mapped_type & -getOr(T && map, const typename T::key_type & key, const typename T::mapped_type & defaultValue) = delete; +/** + * Deleted because this is use-after-free liability. Just don't pass temporaries to this overload set. + */ +template +const typename T::mapped_type & getOr(T && map, const K & key, const typename T::mapped_type & defaultValue) = delete; /** * Remove and return the first item from a container.