blob: 142113ab31ea2f8971cb9b00a3fa2a575e0d0b58 [file] [log] [blame]
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef THIRD_PARTY_CRUBIT_SUPPORT_INTERNAL_MEMSWAP_H_
#define THIRD_PARTY_CRUBIT_SUPPORT_INTERNAL_MEMSWAP_H_
#include <cstring>
#include "absl/base/optimization.h"
namespace crubit {
// Like `std::swap`, but the implementation is guaranteed to have no
// dependencies on `T`-specific code (e.g. it does *not* call into
// `T::operator=`).
//
// SAFETY REQUIREMENTS: Should only be called on `[[clang::trivial_abi]]` (aka
// `std::is_trivially_relocatable`) types.
// TODO(b/290992400): Enforce these safety requirements via
// `static_assert(absl::is_trivially_relocatable<T>::value);`.
template <typename T>
void MemSwap(T& a, T& b) {
if (ABSL_PREDICT_FALSE(&a == &b)) {
return;
}
char tmp[sizeof(T)];
std::memcpy(tmp, &a, sizeof(T));
std::memcpy(&a, &b, sizeof(T));
std::memcpy(&b, tmp, sizeof(T));
}
} // namespace crubit
#endif // THIRD_PARTY_CRUBIT_SUPPORT_INTERNAL_MEMSWAP_H_