-
Notifications
You must be signed in to change notification settings - Fork 380
Add string_view API for c++17 #410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,49 @@ manifest key][links]* in the Cargo reference. | |
|
||
[links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key | ||
|
||
## Features | ||
|
||
CXX provides features to enable additional functionality such as compiling | ||
the CXX lib with a different standard. | ||
|
||
Features are enabled on the CXX crate for Cargo-based setups, and with compiler | ||
options for non-Cargo setups. | ||
|
||
The following features are available, see `[features]` section in [Cargo.toml](https://github.com/dtolnay/cxx/blob/master/Cargo.toml) for a full list: | ||
<table> | ||
<tr><th>feature</th><th>compiler option</th><th>description</th></tr> | ||
<tr><td>c++14</td><td>-std=c++14 (gcc, clang), /std:c++14 (msvc)</td><td>Compile CXX lib with c++14</td></tr> | ||
<tr><td>c++17</td><td>-std=c++17 (gcc, clang), /std:c++17 (msvc)</td><td>Compile CXX lib with c++17</td></tr> | ||
</table> | ||
|
||
## Additional C++ standard features | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential documentation for enabling additional C++ APIs. Nicer to look at page: |
||
Some addition APIs are available if compiling your code with a newer C++ standard. | ||
|
||
Please note, that these additional APIs are automatically enabled in the `cxx.h` | ||
header if your code is compiled with the required minimal C++ standard. They do | ||
not depend on building the actual CXX lib against the newer standard at this time. | ||
|
||
<table> | ||
<tr><th>Minimal C++ standard</th><th>Description</th></tr> | ||
<tr><td>c++17</td><td>Enables additional `string_view` APIs for `rust::str` and `rust::String`</td></tr> | ||
</table> | ||
|
||
Example to e.g. enable the `string_view` APIs for your code, build at least with C++17: | ||
```rust,noplayground | ||
// build.rs | ||
|
||
fn main() { | ||
cxx_build::bridge("src/main.rs") // returns a cc::Build | ||
.file("src/demo.cc") | ||
.flag_if_supported("-std=c++17") | ||
.compile("cxxbridge-demo"); | ||
|
||
println!("cargo:rerun-if-changed=src/main.rs"); | ||
println!("cargo:rerun-if-changed=src/demo.cc"); | ||
println!("cargo:rerun-if-changed=include/demo.h"); | ||
} | ||
``` | ||
|
||
<br><br><br> | ||
|
||
# Advanced features | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,45 @@ | |
#include <basetsd.h> | ||
#endif | ||
|
||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using CXXBRIDGE_.. naming to align more with other defines. WIP used CXX_... naming Bikeshedding time? |
||
#error "string_view gets auto-detected" | ||
#endif | ||
|
||
// clang-format off | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disabling clang-format as settings will flatten everything which makes this hard to follow. Using normal feature detection for compilers supporting it. Feature detection was also noted in the WIP PR. Idea is that if string_view is supported, we should support it. |
||
// detect if string_view supported (C++17 required) | ||
#ifdef __has_include | ||
#if __has_include(<version>) | ||
// gcc >= 9, clang >= 9, msvc >= 19.22 | ||
#include <version> | ||
#if __cpp_lib_string_view >= 201603L | ||
#define CXXBRIDGE_HAS_STRING_VIEW | ||
#endif | ||
#else | ||
// no <version> include | ||
#if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201603L | ||
// gcc: 8, clang: 5 - 8, msvc: 19.15 - 19.21 | ||
#define CXXBRIDGE_HAS_STRING_VIEW | ||
#else | ||
// only include if compiled with c++17 | ||
#if (__GNUC__ >= 7 && __cplusplus >= 201703L) || (_MSVC_LANG >= 201703L) | ||
// gcc: 7, msvc: 19.14 | ||
#define CXXBRIDGE_HAS_STRING_VIEW | ||
#endif | ||
#endif | ||
#endif | ||
#else | ||
// no __has_include | ||
#if _MSC_VER >= 1910L && _MSVC_LANG > 201402L | ||
// msvc: 19.10 requires c++latest (!) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Older msvc compilers that supported string_view. Not sure what compiler versions you want to support, but I've included the ones I could get my hands on through godbolt. There could be a discussion if it would make sense to support "c++latest" in cxx as a feature (for msvc). |
||
#define CPPBRIDGE_HAS_STRING_VIEW | ||
#endif | ||
#endif | ||
// clang-format on | ||
|
||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
#include <string_view> | ||
#endif | ||
|
||
namespace rust { | ||
inline namespace cxxbridge1 { | ||
|
||
|
@@ -34,6 +73,9 @@ class String final { | |
String(String &&) noexcept; | ||
~String() noexcept; | ||
|
||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
String(std::string_view sv) : String(sv.data(), sv.length()) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add "always inline", e.g. |
||
#endif | ||
String(const std::string &); | ||
String(const char *); | ||
String(const char *, size_t); | ||
|
@@ -42,6 +84,11 @@ class String final { | |
String &operator=(String &&) noexcept; | ||
|
||
explicit operator std::string() const; | ||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
explicit operator std::string_view() const noexcept { | ||
return {this->data(), this->size()}; | ||
} | ||
#endif | ||
|
||
// Note: no null terminator. | ||
const char *data() const noexcept; | ||
|
@@ -71,13 +118,21 @@ class String final { | |
class Str final { | ||
public: | ||
Str() noexcept; | ||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
Str(std::string_view sv) : Str(sv.data(), sv.length()) {} | ||
#endif | ||
Str(const std::string &); | ||
Str(const char *); | ||
Str(const char *, size_t); | ||
|
||
Str &operator=(const Str &) noexcept = default; | ||
|
||
explicit operator std::string() const; | ||
#ifdef CXXBRIDGE_HAS_STRING_VIEW | ||
explicit operator std::string_view() const noexcept { | ||
return {this->data(), this->size()}; | ||
} | ||
#endif | ||
|
||
// Note: no null terminator. | ||
const char *data() const noexcept; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if that's the place where you'd want to document features if at all. Just a placeholder.
Nicer to look at page: https://github.com/roligugus/cxx/blob/string_view/book/src/build/cargo.md#features