diff options
-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); |