diff options
author | David Tolnay <dtolnay@gmail.com> | 2021-08-27 13:20:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-27 13:20:35 -0700 |
commit | 800d98989532e519d422b94544e1421c9cb73006 (patch) | |
tree | 69dda3e26ff6e0c96715050fd6dd5917ee1402f5 | |
parent | 36131a0818cee5c64c36b53eeb58d2d42e75adf4 (diff) | |
parent | 8f56cbbaceb349e9d054ee5e88170a199e917d19 (diff) | |
download | cxx-800d98989532e519d422b94544e1421c9cb73006.tar.gz |
Merge pull request #924 from dtolnay/ruststringcap
Expose capacity and reserve on rust::String
-rw-r--r-- | book/src/binding/string.md | 3 | ||||
-rw-r--r-- | include/cxx.h | 3 | ||||
-rw-r--r-- | src/cxx.cc | 11 | ||||
-rw-r--r-- | src/symbols/rust_string.rs | 13 | ||||
-rw-r--r-- | tests/ffi/tests.cc | 6 |
5 files changed, 36 insertions, 0 deletions
diff --git a/book/src/binding/string.md b/book/src/binding/string.md index 533894bc..d564e00c 100644 --- a/book/src/binding/string.md +++ b/book/src/binding/string.md @@ -40,6 +40,9 @@ public: const char *c_str() noexcept; + size_t capacity() const noexcept; + void reserve(size_t new_cap) noexcept; + using iterator = char *; iterator begin() noexcept; iterator end() noexcept; diff --git a/include/cxx.h b/include/cxx.h index 23ebfe8f..dffcb01a 100644 --- a/include/cxx.h +++ b/include/cxx.h @@ -59,6 +59,9 @@ public: const char *c_str() noexcept; + std::size_t capacity() const noexcept; + void reserve(size_t new_cap) noexcept; + using iterator = char *; iterator begin() noexcept; iterator end() noexcept; @@ -40,8 +40,11 @@ bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, void cxxbridge1$string$drop(rust::String *self) noexcept; const char *cxxbridge1$string$ptr(const rust::String *self) noexcept; std::size_t cxxbridge1$string$len(const rust::String *self) noexcept; +std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept; void cxxbridge1$string$reserve_additional(rust::String *self, size_t additional) noexcept; +void cxxbridge1$string$reserve_total(rust::String *self, + size_t new_cap) noexcept; // rust::Str void cxxbridge1$str$new(rust::Str *self) noexcept; @@ -165,6 +168,14 @@ const char *String::c_str() noexcept { return ptr; } +std::size_t String::capacity() const noexcept { + return cxxbridge1$string$capacity(this); +} + +void String::reserve(std::size_t new_cap) noexcept { + cxxbridge1$string$reserve_total(this, new_cap); +} + String::iterator String::begin() noexcept { return const_cast<char *>(this->data()); } diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs index 202c55fc..49d40697 100644 --- a/src/symbols/rust_string.rs +++ b/src/symbols/rust_string.rs @@ -69,7 +69,20 @@ unsafe extern "C" fn string_len(this: &String) -> usize { this.len() } +#[export_name = "cxxbridge1$string$capacity"] +unsafe extern "C" fn string_capacity(this: &String) -> usize { + this.capacity() +} + #[export_name = "cxxbridge1$string$reserve_additional"] unsafe extern "C" fn string_reserve_additional(this: &mut String, additional: usize) { this.reserve(additional); } + +#[export_name = "cxxbridge1$string$reserve_total"] +unsafe extern "C" fn string_reserve_total(this: &mut String, new_cap: usize) { + if new_cap > this.capacity() { + let additional = new_cap - this.len(); + this.reserve(additional); + } +} diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc index d153cd16..df7ded07 100644 --- a/tests/ffi/tests.cc +++ b/tests/ffi/tests.cc @@ -835,6 +835,12 @@ extern "C" const char *cxx_run_test() noexcept { ASSERT(cstring == "foo"); ASSERT(other_cstring == "test"); + ASSERT(cstring.capacity() == 3); + cstring.reserve(2); + ASSERT(cstring.capacity() == 3); + cstring.reserve(5); + ASSERT(cstring.capacity() >= 5); + rust::Str cstr = "test"; rust::Str other_cstr = "foo"; swap(cstr, other_cstr); |