if (std::is_trivially_copyable<T>() && sizeof(T) < 256)
#endif
{
+ // Determine the size. There are places where we would like to use a
+ // truly empty type, for which we use std::tuple<> (i.e., a tuple
+ // of zero elements). For this class, the compiler reports a nonzero
+ // sizeof(...) because that is the minimum possible for objects --
+ // objects need to have distinct addresses, so they need to have a size
+ // of at least one. But we can special case this situation.
+ size = (std::is_same<T, std::tuple<>>::value ? 0 : sizeof(T));
+
(void)allow_compression;
const std::size_t previous_size = dest_buffer.size();
- dest_buffer.resize(previous_size + sizeof(T));
-
- std::memcpy(dest_buffer.data() + previous_size, &object, sizeof(T));
+ dest_buffer.resize(previous_size + size);
- size = sizeof(T);
+ if (size > 0)
+ std::memcpy(dest_buffer.data() + previous_size, &object, size);
}
// Next try if we have a vector of trivially copyable objects.
// If that is the case, we can shortcut the whole BOOST serialization
if (std::is_trivially_copyable<T>() && sizeof(T) < 256)
#endif
{
+ // Determine the size. There are places where we would like to use a
+ // truly empty type, for which we use std::tuple<> (i.e., a tuple
+ // of zero elements). For this class, the compiler reports a nonzero
+ // sizeof(...) because that is the minimum possible for objects --
+ // objects need to have distinct addresses, so they need to have a size
+ // of at least one. But we can special case this situation.
+ const std::size_t size =
+ (std::is_same<T, std::tuple<>>::value ? 0 : sizeof(T));
+
T object;
(void)allow_compression;
- Assert(std::distance(cbegin, cend) == sizeof(T), ExcInternalError());
- std::memcpy(&object, &*cbegin, sizeof(T));
+ Assert(std::distance(cbegin, cend) == size, ExcInternalError());
+
+ if (size > 0)
+ std::memcpy(&object, &*cbegin, size);
return object;
}
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2017 - 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+// Make sure that Utilities::pack/unpack can be used on objects that
+// are empty, and that the resulting packed string has length zero.
+
+
+#include <deal.II/base/point.h>
+#include <deal.II/base/timer.h>
+#include <deal.II/base/utilities.h>
+
+#include <tuple>
+
+#include "../tests.h"
+
+
+
+void
+test()
+{
+ using Empty = std::tuple<>;
+
+ Empty e;
+ deallog << "Size = " << sizeof(e) << std::endl;
+
+ // Pack the object and make sure the packed length is zero
+ const std::vector<char> packed = Utilities::pack(e, false);
+ deallog << "Packed size = " << packed.size() << std::endl;
+
+ // Then unpack again. The two should be the same -- though one may
+ // question what equality of objects of size zero might mean -- and
+ // we should check so:
+ Empty e2 = Utilities::unpack<Empty>(packed, false);
+ Assert(e2 == e, ExcInternalError());
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+int
+main()
+{
+ initlog();
+
+ test();
+}