aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2021-08-27 13:20:35 -0700
committerGitHub <noreply@github.com>2021-08-27 13:20:35 -0700
commit800d98989532e519d422b94544e1421c9cb73006 (patch)
tree69dda3e26ff6e0c96715050fd6dd5917ee1402f5
parent36131a0818cee5c64c36b53eeb58d2d42e75adf4 (diff)
parent8f56cbbaceb349e9d054ee5e88170a199e917d19 (diff)
downloadcxx-800d98989532e519d422b94544e1421c9cb73006.tar.gz
Merge pull request #924 from dtolnay/ruststringcap
Expose capacity and reserve on rust::String
-rw-r--r--book/src/binding/string.md3
-rw-r--r--include/cxx.h3
-rw-r--r--src/cxx.cc11
-rw-r--r--src/symbols/rust_string.rs13
-rw-r--r--tests/ffi/tests.cc6
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;
diff --git a/src/cxx.cc b/src/cxx.cc
index 921b17db..2a615483 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -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);