Skip to content

Commit 96a8e8a

Browse files
committed
Prevent extraneous default construction when decoding maps
The `operator[]` on `std::map` will default construct the value if it does not exist, and then move assign it the requested value. By using the C++17 method `insert_or_assign`, we prevent that extra object construction.
1 parent 0a09cfe commit 96a8e8a

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

include/fine.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ struct Decoder<std::map<K, V, Compare, Alloc>> {
667667
}
668668
}();
669669

670-
ERL_NIF_TERM key, value;
670+
ERL_NIF_TERM key_term, value_term;
671671
ErlNifMapIterator iter;
672672
if (!enif_map_iterator_create(env, term, &iter,
673673
ERL_NIF_MAP_ITERATOR_FIRST)) {
@@ -677,8 +677,12 @@ struct Decoder<std::map<K, V, Compare, Alloc>> {
677677
// Define RAII cleanup for the iterator
678678
auto cleanup = IterCleanup{env, iter};
679679

680-
while (enif_map_iterator_get_pair(env, &iter, &key, &value)) {
681-
map[fine::decode<K>(env, key)] = fine::decode<V>(env, value);
680+
while (enif_map_iterator_get_pair(env, &iter, &key_term, &value_term)) {
681+
auto key = fine::decode<K>(env, key_term);
682+
auto value = fine::decode<V>(env, value_term);
683+
684+
map.insert_or_assign(std::move(key), std::move(value));
685+
682686
enif_map_iterator_next(env, &iter);
683687
}
684688

@@ -899,7 +903,7 @@ template <typename... Args> struct Encoder<std::tuple<Args...>> {
899903
template <typename T, typename Alloc> struct Encoder<std::vector<T, Alloc>> {
900904
static ERL_NIF_TERM encode(ErlNifEnv *env,
901905
const std::vector<T, Alloc> &vector) {
902-
auto terms = std::vector<ERL_NIF_TERM, fine::Allocator<ERL_NIF_TERM>>();
906+
auto terms = std_vector<ERL_NIF_TERM>();
903907
terms.reserve(vector.size());
904908

905909
for (const auto &item : vector) {
@@ -915,8 +919,8 @@ template <typename K, typename V, typename Compare, typename Alloc>
915919
struct Encoder<std::map<K, V, Compare, Alloc>> {
916920
static ERL_NIF_TERM encode(ErlNifEnv *env,
917921
const std::map<K, V, Compare, Alloc> &map) {
918-
auto keys = std::vector<ERL_NIF_TERM, fine::Allocator<ERL_NIF_TERM>>();
919-
auto values = std::vector<ERL_NIF_TERM, fine::Allocator<ERL_NIF_TERM>>();
922+
auto keys = std_vector<ERL_NIF_TERM>();
923+
auto values = std_vector<ERL_NIF_TERM>();
920924

921925
for (const auto &[key, value] : map) {
922926
keys.push_back(fine::encode(env, key));

0 commit comments

Comments
 (0)