blob: 5818ca49d561c607621d13d9ff8956599d180a43 [file] [log] [blame] [edit]
// 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 CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NONUNPIN_NONUNPIN_H_
#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NONUNPIN_NONUNPIN_H_
#include <cstddef>
#include <utility>
#include "absl/log/check.h"
#pragma clang lifetime_elision
// A deliberately !Unpin class.
class Nonunpin {
public:
Nonunpin() { CheckInvariant(); }
explicit Nonunpin(int value) : value_(value) { CheckInvariant(); }
Nonunpin(const Nonunpin& other) : Nonunpin(other.value_) { CheckInvariant(); }
// We have a nonconventional assignment operator which returns a
// non-trivially-relocatable value, by value.
//
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
Nonunpin operator=(const Nonunpin& other) {
CheckInvariant();
value_ = other.value_;
return *this;
}
Nonunpin(Nonunpin&& other) : Nonunpin(other.value_) {
CheckInvariant();
other.value_ = 0;
}
Nonunpin& operator=(Nonunpin&& other) {
CheckInvariant();
value_ = other.value_;
other.value_ = 0;
return *this;
}
~Nonunpin() { CheckInvariant(); }
size_t addr() const {
CheckInvariant();
return addr_;
}
int value() const {
CheckInvariant();
return value_;
}
void set_value(int new_value) {
CheckInvariant();
value_ = new_value;
}
Nonunpin& AsMutRef() {
CheckInvariant();
return *this;
}
Nonunpin&& AsRvalueRef() {
CheckInvariant();
return std::move(*this);
}
const Nonunpin& AsConstRef() const {
CheckInvariant();
return *this;
}
const Nonunpin&& AsConstRvalueRef() const {
CheckInvariant();
return std::move(*this);
}
Nonunpin AsValue() const {
CheckInvariant();
return *this;
}
private:
void CheckInvariant() const {
CHECK_EQ(reinterpret_cast<const void*>(addr_),
static_cast<const void*>(this))
<< "Object was trivially relocated, but that is not supported.";
}
int value_ = 0;
size_t addr_ = reinterpret_cast<size_t>(this);
};
inline int GetValueFromMutRef(Nonunpin& nonunpin) { return nonunpin.value(); }
inline int GetValueFromConstRef(const Nonunpin& nonunpin) {
return nonunpin.value();
}
inline int GetValueFromRvalueRef(Nonunpin&& nonunpin) {
return nonunpin.value();
}
inline int GetValueFromConstRvalueRef(const Nonunpin&& nonunpin) {
return nonunpin.value();
}
inline int GetValueFromValue(Nonunpin nonunpin) { return nonunpin.value(); }
// A deliberately !Unpin (aggregate) struct.
struct NonunpinStruct {
int value;
~NonunpinStruct() {}
};
// A deliberately non-movable, non-copyable struct. (And, therefore, !Unpin).
struct Nonmovable final {
Nonmovable() : addr(reinterpret_cast<uintptr_t>(this)) {}
Nonmovable(const Nonmovable&) = delete;
Nonmovable(Nonmovable&&) = delete;
// The address at the time of construction.
uintptr_t addr;
};
inline Nonmovable ReturnsNonmovable() { return Nonmovable(); }
// This doesn't receive bindings, because parameter types must be movable.
inline Nonmovable DisabledFunction(Nonmovable) { return Nonmovable(); }
#endif // CRUBIT_RS_BINDINGS_FROM_CC_TEST_STRUCT_NONUNPIN_NONUNPIN_H_