16 #ifndef dealii_utilities_h
17 #define dealii_utilities_h
26 #include <type_traits>
31 #ifdef DEAL_II_WITH_TRILINOS
32 # include <Epetra_Comm.h>
33 # include <Epetra_Map.h>
34 # include <Teuchos_Comm.hpp>
35 # include <Teuchos_RCP.hpp>
36 # ifdef DEAL_II_WITH_MPI
37 # include <Epetra_MpiComm.h>
39 # include <Epetra_SerialComm.h>
45 #include <boost/archive/binary_iarchive.hpp>
46 #include <boost/archive/binary_oarchive.hpp>
47 #include <boost/core/demangle.hpp>
48 #include <boost/serialization/array.hpp>
49 #include <boost/serialization/complex.hpp>
50 #include <boost/serialization/vector.hpp>
52 #ifdef DEAL_II_WITH_ZLIB
53 # include <boost/iostreams/device/back_inserter.hpp>
54 # include <boost/iostreams/filter/gzip.hpp>
55 # include <boost/iostreams/filtering_stream.hpp>
56 # include <boost/iostreams/stream.hpp>
65 template <
int dim,
typename Number>
104 template <
int dim,
typename Number>
105 std::vector<std::array<std::uint64_t, dim>>
108 const int bits_per_dim = 64);
114 std::vector<std::array<std::uint64_t, dim>>
116 const std::vector<std::array<std::uint64_t, dim>> &points,
117 const int bits_per_dim = 64);
137 const int bits_per_dim);
172 decompress(
const std::string &compressed_input);
190 encode_base64(
const std::vector<unsigned char> &binary_input);
202 std::vector<unsigned char>
241 template <
typename number>
265 template <
typename Number>
288 dim_string(
const int dim,
const int spacedim);
355 std::vector<std::string>
363 std::vector<std::string>
376 std::vector<std::string>
378 const unsigned int width,
379 const char delimiter =
' ');
396 std::pair<int, unsigned int>
405 const std::string &from,
406 const std::string &to);
414 trim(
const std::string &input);
465 template <
int N,
typename T>
474 template <
typename T>
476 pow(
const T base,
const int iexp)
478 #if defined(DEBUG) && defined(DEAL_II_HAVE_CXX14_CONSTEXPR)
488 "ExcMessage(\"The exponent must not be negative!\")",
489 ExcMessage(
"The exponent must not be negative!"));
517 (((iexp % 2 == 1) ? base : 1) *
542 template <
typename Iterator,
typename T>
552 template <
typename Iterator,
typename T,
typename Comp>
561 template <
typename Integer>
570 template <
typename Integer>
591 template <
typename T>
593 pack(
const T &
object,
594 std::vector<char> &dest_buffer,
595 const bool allow_compression =
true);
607 template <
typename T>
609 pack(
const T &
object,
const bool allow_compression =
true);
643 template <
typename T>
645 unpack(
const std::vector<char> &buffer,
const bool allow_compression =
true);
657 template <
typename T>
659 unpack(
const std::vector<char>::const_iterator &cbegin,
660 const std::vector<char>::const_iterator &cend,
661 const bool allow_compression =
true);
697 template <
typename T,
int N>
699 unpack(
const std::vector<char> &buffer,
700 T (&unpacked_object)[
N],
701 const bool allow_compression =
true);
713 template <
typename T,
int N>
715 unpack(
const std::vector<char>::const_iterator &cbegin,
716 const std::vector<char>::const_iterator &cend,
717 T (&unpacked_object)[
N],
718 const bool allow_compression =
true);
777 template <
typename To,
typename From>
784 if (To *cast =
dynamic_cast<To *
>(p.get()))
786 std::unique_ptr<To> result(cast);
791 throw std::bad_cast();
919 posix_memalign(
void **memptr, std::size_t alignment, std::size_t size);
923 #ifdef DEAL_II_WITH_TRILINOS
963 const Teuchos::RCP<const Teuchos::Comm<int>> &
1057 duplicate_map(
const Epetra_BlockMap &map,
const Epetra_Comm &comm);
1070 template <
int N,
typename T>
1077 "The non-type template parameter N must be a non-negative integer for integral type T"));
1086 fixed_power<N / 2>(x * x));
1095 return boost::core::demangle(
typeid(t).name());
1100 template <
typename Iterator,
typename T>
1109 template <
typename Iterator,
typename T,
typename Comp>
1118 "The given iterators do not satisfy the proper ordering."));
1120 unsigned int len =
static_cast<unsigned int>(last -
first);
1137 if (!comp(*
first, val))
1142 if (!comp(*
first, val))
1147 if (!comp(*
first, val))
1152 if (!comp(*
first, val))
1157 if (!comp(*
first, val))
1162 if (!comp(*
first, val))
1167 if (!comp(*
first, val))
1186 const unsigned int half = len >> 1;
1194 if (comp(*middle, val))
1207 template <
typename T>
1210 std::vector<char> &dest_buffer,
1211 const bool allow_compression)
1214 (void)allow_compression;
1216 std::size_t size = 0;
1225 #if __GNUG__ && __GNUC__ < 5
1226 if (__has_trivial_copy(
T) &&
sizeof(
T) < 256)
1228 # ifdef DEAL_II_WITH_CXX17
1229 if constexpr (std::is_trivially_copyable<T>() &&
sizeof(
T) < 256)
1231 if (std::is_trivially_copyable<T>() &&
sizeof(
T) < 256)
1235 const std::size_t previous_size = dest_buffer.size();
1236 dest_buffer.resize(previous_size +
sizeof(
T));
1238 std::memcpy(dest_buffer.data() + previous_size, &
object,
sizeof(
T));
1246 const std::size_t previous_size = dest_buffer.size();
1247 #ifdef DEAL_II_WITH_ZLIB
1248 if (allow_compression)
1250 boost::iostreams::filtering_ostream out;
1252 boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
1253 boost::iostreams::gzip::default_compression)));
1254 out.push(boost::iostreams::back_inserter(dest_buffer));
1256 boost::archive::binary_oarchive archive(out);
1263 std::ostringstream out;
1264 boost::archive::binary_oarchive archive(out);
1267 const std::string s = out.str();
1268 dest_buffer.reserve(dest_buffer.size() + s.size());
1269 std::move(s.begin(), s.end(), std::back_inserter(dest_buffer));
1272 size = dest_buffer.size() - previous_size;
1279 template <
typename T>
1281 pack(
const T &
object,
const bool allow_compression)
1283 std::vector<char> buffer;
1284 pack<T>(
object, buffer, allow_compression);
1289 template <
typename T>
1291 unpack(
const std::vector<char>::const_iterator &cbegin,
1292 const std::vector<char>::const_iterator &cend,
1293 const bool allow_compression)
1298 (void)allow_compression;
1307 #if __GNUG__ && __GNUC__ < 5
1308 if (__has_trivial_copy(
T) &&
sizeof(
T) < 256)
1310 # ifdef DEAL_II_WITH_CXX17
1311 if constexpr (std::is_trivially_copyable<T>() &&
sizeof(
T) < 256)
1313 if (std::is_trivially_copyable<T>() &&
sizeof(
T) < 256)
1318 std::memcpy(&
object, &*cbegin,
sizeof(
T));
1322 std::string decompressed_buffer;
1325 #ifdef DEAL_II_WITH_ZLIB
1326 if (allow_compression)
1328 boost::iostreams::filtering_ostream decompressing_stream;
1329 decompressing_stream.push(boost::iostreams::gzip_decompressor());
1330 decompressing_stream.push(
1331 boost::iostreams::back_inserter(decompressed_buffer));
1332 decompressing_stream.write(&*cbegin, std::distance(cbegin, cend));
1337 decompressed_buffer.assign(cbegin, cend);
1341 std::istringstream in(decompressed_buffer);
1342 boost::archive::binary_iarchive archive(in);
1351 template <
typename T>
1353 unpack(
const std::vector<char> &buffer,
const bool allow_compression)
1355 return unpack<T>(buffer.cbegin(), buffer.cend(), allow_compression);
1359 template <
typename T,
int N>
1361 unpack(
const std::vector<char>::const_iterator &cbegin,
1362 const std::vector<char>::const_iterator &cend,
1363 T (&unpacked_object)[
N],
1364 const bool allow_compression)
1374 #
if __GNUG__ && __GNUC__ < 5
1375 __has_trivial_copy(
T)
1377 std::is_trivially_copyable<T>()
1379 &&
sizeof(
T) *
N < 256)
1381 Assert(std::distance(cbegin, cend) ==
sizeof(
T) *
N,
1383 std::memcpy(unpacked_object, &*cbegin,
sizeof(
T) *
N);
1387 std::string decompressed_buffer;
1390 (void)allow_compression;
1391 #ifdef DEAL_II_WITH_ZLIB
1392 if (allow_compression)
1394 boost::iostreams::filtering_ostream decompressing_stream;
1395 decompressing_stream.push(boost::iostreams::gzip_decompressor());
1396 decompressing_stream.push(
1397 boost::iostreams::back_inserter(decompressed_buffer));
1398 decompressing_stream.write(&*cbegin, std::distance(cbegin, cend));
1403 decompressed_buffer.assign(cbegin, cend);
1407 std::istringstream in(decompressed_buffer);
1408 boost::archive::binary_iarchive archive(in);
1410 archive >> unpacked_object;
1415 template <
typename T,
int N>
1418 T (&unpacked_object)[
N],
1419 const bool allow_compression)
1421 unpack<T, N>(buffer.cbegin(),
1429 template <
typename Integer>
1430 std::vector<Integer>
1433 const std::size_t n = permutation.size();
1435 std::vector<Integer> out(n);
1436 for (std::size_t i = 0; i < n; ++i)
1437 out[i] = n - 1 - permutation[i];
1444 template <
typename Integer>
1445 std::vector<Integer>
1448 const std::size_t n = permutation.size();
1452 for (std::size_t i = 0; i < n; ++i)
1455 out[permutation[i]] = i;
1460 for (std::size_t i = 0; i < n; ++i)
1462 ExcMessage(
"The given input permutation had duplicate entries!"));
1474 namespace serialization
1481 template <
class Archive,
typename... Args>
1483 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1485 ar &std::get<
N - 1>(t);
1486 Serialize<N - 1>::serialize(ar, t, version);
1493 template <
class Archive,
typename... Args>
1495 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1503 template <
class Archive,
typename... Args>
1505 serialize(Archive &ar, std::tuple<Args...> &t,
const unsigned int version)
1507 Serialize<
sizeof...(Args)>::serialize(ar, t, version);