2222
2323#include < sstream>
2424#include < stdexcept>
25+ #include < type_traits>
2526
2627namespace datasketches {
2728
@@ -461,7 +462,6 @@ req_sketch<T, C, A> req_sketch<T, C, A>::deserialize(std::istream& is, const Ser
461462 const bool hra = flags_byte & (1 << flags::IS_HIGH_RANK );
462463 if (is_empty) return req_sketch (k, hra, comparator, allocator);
463464
464- optional<T> tmp; // space to deserialize min and max
465465 optional<T> min_item;
466466 optional<T> max_item;
467467
@@ -472,14 +472,19 @@ req_sketch<T, C, A> req_sketch<T, C, A>::deserialize(std::istream& is, const Ser
472472 uint64_t n = 1 ;
473473 if (num_levels > 1 ) {
474474 n = read<uint64_t >(is);
475- sd.deserialize (is, &*tmp, 1 );
475+ // Space to deserialize min and max.
476+ // serde::deserialize expects allocated but not initialized storage.
477+ typename std::aligned_storage<sizeof (T), alignof (T)>::type tmp_storage;
478+ T* tmp = reinterpret_cast <T*>(&tmp_storage);
479+
480+ sd.deserialize (is, tmp, 1 );
476481 // serde call did not throw, repackage and cleanup
477- min_item.emplace (*tmp);
478- (* tmp). ~T ();
479- sd.deserialize (is, &* tmp, 1 );
482+ min_item.emplace (std::move ( *tmp) );
483+ tmp-> ~T ();
484+ sd.deserialize (is, tmp, 1 );
480485 // serde call did not throw, repackage and cleanup
481- max_item.emplace (*tmp);
482- (* tmp). ~T ();
486+ max_item.emplace (std::move ( *tmp) );
487+ tmp-> ~T ();
483488 }
484489
485490 if (raw_items) {
@@ -537,7 +542,6 @@ req_sketch<T, C, A> req_sketch<T, C, A>::deserialize(const void* bytes, size_t s
537542 const bool hra = flags_byte & (1 << flags::IS_HIGH_RANK );
538543 if (is_empty) return req_sketch (k, hra, comparator, allocator);
539544
540- optional<T> tmp; // space to deserialize min and max
541545 optional<T> min_item;
542546 optional<T> max_item;
543547
@@ -549,14 +553,19 @@ req_sketch<T, C, A> req_sketch<T, C, A>::deserialize(const void* bytes, size_t s
549553 if (num_levels > 1 ) {
550554 ensure_minimum_memory (end_ptr - ptr, sizeof (n));
551555 ptr += copy_from_mem (ptr, n);
552- ptr += sd.deserialize (ptr, end_ptr - ptr, &*tmp, 1 );
556+ // Space to deserialize min and max.
557+ // serde::deserialize expects allocated but not initialized storage.
558+ typename std::aligned_storage<sizeof (T), alignof (T)>::type tmp_storage;
559+ T* tmp = reinterpret_cast <T*>(&tmp_storage);
560+
561+ ptr += sd.deserialize (ptr, end_ptr - ptr, tmp, 1 );
553562 // serde call did not throw, repackage and cleanup
554- min_item.emplace (*tmp);
555- (* tmp). ~T ();
556- ptr += sd.deserialize (ptr, end_ptr - ptr, &* tmp, 1 );
563+ min_item.emplace (std::move ( *tmp) );
564+ tmp-> ~T ();
565+ ptr += sd.deserialize (ptr, end_ptr - ptr, tmp, 1 );
557566 // serde call did not throw, repackage and cleanup
558- max_item.emplace (*tmp);
559- (* tmp). ~T ();
567+ max_item.emplace (std::move ( *tmp) );
568+ tmp-> ~T ();
560569 }
561570
562571 if (raw_items) {
0 commit comments