Merge pull request 642 from capickett/swap

This commit is contained in:
David Tolnay 2021-01-02 12:04:19 -08:00
commit 756556e23c
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
8 changed files with 94 additions and 1 deletions

View File

@ -25,6 +25,8 @@ public:
explicit Box(const T &);
explicit Box(T &&);
void swap(Box &) noexcept;
Box &operator=(const Box &);
Box &operator=(Box &&) noexcept;

View File

@ -32,6 +32,8 @@ public:
size_t length() const noexcept;
bool empty() const noexcept;
void swap(Slice & rhs) noexcept;
T &operator[](size_t n) const noexcept;
T &at(size_t n) const;
T &front() const noexcept;

View File

@ -31,6 +31,8 @@ public:
size_t size() const noexcept;
size_t length() const noexcept;
void swap(Str & rhs) noexcept;
using iterator = const char *;
using const_iterator = const char *;
const_iterator begin() const noexcept;

View File

@ -35,6 +35,8 @@ public:
const char *c_str() noexcept;
void swap(String & rhs) noexcept;
using iterator = char *;
iterator begin() noexcept;
iterator end() noexcept;

View File

@ -31,6 +31,8 @@ public:
const T *data() const noexcept;
T *data() noexcept;
size_t capacity() const noexcept;
void swap(Vec & rhs) noexcept;
const T &operator[](size_t n) const noexcept;
const T &at(size_t n) const;

View File

@ -56,6 +56,8 @@ public:
const char *c_str() noexcept;
void swap(String & rhs) noexcept;
using iterator = char *;
iterator begin() noexcept;
iterator end() noexcept;
@ -77,9 +79,14 @@ public:
String(unsafe_bitcopy_t, const String &) noexcept;
private:
friend void swap(String& lhs, String& rhs) noexcept {
lhs.swap(rhs);
}
// Size and alignment statically verified by rust_string.rs.
std::array<std::uintptr_t, 3> repr;
};
#endif // CXXBRIDGE1_RUST_STRING
#ifndef CXXBRIDGE1_RUST_STR
@ -101,6 +108,8 @@ public:
std::size_t size() const noexcept;
std::size_t length() const noexcept;
void swap(Str & rhs) noexcept;
// Important in order for System V ABI to pass in registers.
Str(const Str &) noexcept = default;
~Str() noexcept = default;
@ -120,6 +129,10 @@ public:
bool operator>=(const Str &) const noexcept;
private:
friend void swap(Str & lhs, Str & rhs) noexcept {
lhs.swap(rhs);
}
// Not necessarily ABI compatible with &str. Codegen will translate to
// cxx::rust_str::RustStr which matches this layout.
const char *ptr;
@ -159,6 +172,8 @@ public:
std::size_t length() const noexcept;
bool empty() const noexcept;
void swap(Slice & rhs) noexcept;
T &operator[](std::size_t n) const noexcept;
T &at(std::size_t n) const;
T &front() const noexcept;
@ -173,6 +188,10 @@ public:
iterator end() const noexcept;
private:
friend void swap(Slice<T> & lhs, Slice<T> & rhs) noexcept {
lhs.swap(rhs);
}
// Not necessarily ABI compatible with &[T]. Codegen will translate to
// cxx::rust_slice::RustSlice which matches this layout.
void *ptr;
@ -234,6 +253,8 @@ public:
explicit Box(const T &);
explicit Box(T &&);
void swap(Box & rhs) noexcept;
Box &operator=(Box &&) noexcept;
const T *operator->() const noexcept;
@ -257,6 +278,11 @@ private:
class allocation;
Box(uninit) noexcept;
void drop() noexcept;
friend void swap(Box & lhs, Box & rhs) noexcept {
lhs.swap(rhs);
}
T *ptr;
};
#endif // CXXBRIDGE1_RUST_BOX
@ -283,6 +309,8 @@ public:
T *data() noexcept;
std::size_t capacity() const noexcept;
void swap(Vec & rhs) noexcept;
const T &operator[](std::size_t n) const noexcept;
const T &at(std::size_t n) const;
const T &front() const noexcept;
@ -317,6 +345,10 @@ private:
void set_len(std::size_t len) noexcept;
void drop() noexcept;
friend void swap(Vec<T> & lhs, Vec<T> & rhs) noexcept {
lhs.swap(rhs);
}
// Size and alignment statically verified by rust_vec.rs.
std::array<std::uintptr_t, 3> repr;
};
@ -504,6 +536,13 @@ std::size_t Slice<T>::length() const noexcept {
return this->len;
}
template <typename T>
void Slice<T>::swap(Slice<T> & rhs) noexcept {
using std::swap;
swap(this->ptr, rhs.ptr);
swap(this->len, rhs.len);
}
template <typename T>
bool Slice<T>::empty() const noexcept {
return this->len == 0;
@ -706,6 +745,12 @@ Box<T>::Box(T &&val) {
alloc.ptr = nullptr;
}
template <typename T>
void Box<T>::swap(Box<T> & rhs) noexcept {
using std::swap;
swap(this->ptr, rhs.ptr);
}
template <typename T>
Box<T>::~Box() noexcept {
if (this->ptr) {
@ -824,6 +869,12 @@ T *Vec<T>::data() noexcept {
return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
}
template <typename T>
void Vec<T>::swap(Vec<T> & rhs) noexcept {
using std::swap;
swap(this->repr, rhs.repr);
}
template <typename T>
const T &Vec<T>::operator[](std::size_t n) const noexcept {
assert(n < this->size());

View File

@ -130,6 +130,11 @@ const char *String::c_str() noexcept {
return ptr;
}
void String::swap(String& rhs) noexcept {
using std::swap;
swap(this->repr, rhs.repr);
}
String::iterator String::begin() noexcept {
return const_cast<char *>(this->data());
}
@ -210,6 +215,12 @@ Str::operator std::string() const {
return std::string(this->data(), this->size());
}
void Str::swap(Str& rhs) noexcept {
using std::swap;
swap(this->ptr, rhs.ptr);
swap(this->len, rhs.len);
}
Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
Str::const_iterator Str::end() const noexcept { return this->cend(); }

View File

@ -751,8 +751,12 @@ extern "C" const char *cxx_run_test() noexcept {
ASSERT(r->get() == 2020);
ASSERT(r->set(2021) == 2021);
ASSERT(r->get() == 2021);
ASSERT(r->set(2020) == 2020);
auto r2 = r_return_box();
swap(r, r2);
ASSERT(r->get() == 2020);
ASSERT(r2->get() == 2021);
ASSERT(std::string(Shared{0}.r_method_on_shared()) == "2020");
ASSERT(std::string(rAliasedFunction(2020)) == "2020");
@ -785,6 +789,23 @@ extern "C" const char *cxx_run_test() noexcept {
ASSERT(strncmp(cstring.c_str(), "test", 5) == 0);
ASSERT(cstring.length() == 4);
rust::String other_cstring = "foo";
swap(cstring, other_cstring);
ASSERT(cstring == "foo");
ASSERT(other_cstring == "test");
rust::Str cstr = "test";
rust::Str other_cstr = "foo";
swap(cstr, other_cstr);
ASSERT(cstr == "foo");
ASSERT(other_cstr == "test");
rust::Vec<int> vec1{1, 2};
rust::Vec<int> vec2{3, 4};
swap(vec1, vec2);
ASSERT(vec1[0] == 3 && vec1[1] == 4);
ASSERT(vec2[0] == 1 && vec2[1] == 2);
cxx_test_suite_set_correct();
return nullptr;
}