Merge pull request #257 from rinon/rust_vec_accessors

Add rust::Vec accessors
This commit is contained in:
David Tolnay 2020-08-26 21:49:23 -07:00 committed by GitHub
commit fb8ddd8eb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 6 deletions

View File

@ -5,6 +5,7 @@
#include <exception>
#include <iosfwd>
#include <new>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
@ -13,6 +14,26 @@
#include <BaseTsd.h>
#endif
#ifndef __has_feature
#define __has_feature(__x) 0
#endif
#if !__has_feature(cxx_exceptions)
# define _CXXBRIDGE03_NO_EXCEPTIONS
#endif
#if !__EXCEPTIONS
# define _CXXBRIDGE03_NO_EXCEPTIONS
#endif
[[noreturn]] inline static void throw_out_of_range(const char *msg) {
#ifndef _CXXBRIDGE03_NO_EXCEPTIONS
throw std::out_of_range(msg);
#else
((void)msg);
std::abort();
#endif
}
namespace rust {
inline namespace cxxbridge03 {
@ -175,6 +196,12 @@ public:
bool empty() const noexcept;
const T *data() const noexcept;
const T &operator[](size_t n) const noexcept;
const T &at(size_t n) const;
const T &front() const;
const T &back() const;
class const_iterator {
public:
using difference_type = ptrdiff_t;
@ -463,6 +490,29 @@ bool Vec<T>::empty() const noexcept {
return size() == 0;
}
template <typename T>
const T &Vec<T>::operator[](size_t n) const noexcept {
auto data = reinterpret_cast<const char *>(this->data());
return *reinterpret_cast<const T *>(data + n * this->stride());
}
template <typename T>
const T &Vec<T>::at(size_t n) const {
if (n >= this->size())
throw_out_of_range("Vec");
return (*this)[n];
}
template <typename T>
const T &Vec<T>::front() const {
return (*this)[0];
}
template <typename T>
const T &Vec<T>::back() const {
return (*this)[this->size()-1];
}
template <typename T>
const T &Vec<T>::const_iterator::operator*() const noexcept {
return *static_cast<const T *>(this->pos);

View File

@ -11,6 +11,7 @@ use std::fmt::{self, Display};
#[cxx::bridge(namespace = tests)]
pub mod ffi {
#[derive(Clone)]
struct Shared {
z: usize,
}
@ -61,8 +62,11 @@ pub mod ffi {
fn c_take_ref_vector(v: &CxxVector<u8>);
fn c_take_rust_vec(v: Vec<u8>);
fn c_take_rust_vec_shared(v: Vec<Shared>);
fn c_take_rust_vec_index(v: Vec<u8>);
fn c_take_rust_vec_shared_index(v: Vec<Shared>);
fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>);
fn c_take_ref_rust_vec(v: &Vec<u8>);
fn c_take_ref_rust_vec_index(v: &Vec<u8>);
fn c_take_ref_rust_vec_copy(v: &Vec<u8>);
/*
// https://github.com/dtolnay/cxx/issues/232

View File

@ -209,6 +209,8 @@ void c_take_ref_vector(const std::vector<uint8_t> &v) {
void c_take_rust_vec(rust::Vec<uint8_t> v) { c_take_ref_rust_vec(v); }
void c_take_rust_vec_index(rust::Vec<uint8_t> v) { c_take_ref_rust_vec_index(v); }
void c_take_rust_vec_shared(rust::Vec<Shared> v) {
uint32_t sum = 0;
for (auto i : v) {
@ -231,6 +233,17 @@ void c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v) {
}
}
void c_take_rust_vec_shared_index(rust::Vec<Shared> v) {
if (v[0].z == 1010 &&
v.at(0).z == 1010 &&
v.front().z == 1010 &&
v[1].z == 1011 &&
v.at(1).z == 1011 &&
v.back().z == 1011) {
cxx_test_suite_set_correct();
}
}
void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v) {
uint8_t sum = std::accumulate(v.begin(), v.end(), 0);
if (sum == 200) {
@ -238,6 +251,19 @@ void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v) {
}
}
void c_take_ref_rust_vec_index(const rust::Vec<uint8_t> &v) {
if (v[0] == 86 &&
v.at(0) == 86 &&
v.front() == 86 &&
v[1] == 75 &&
v.at(1) == 75 &&
v[3] == 9 &&
v.at(3) == 9 &&
v.back() == 9) {
cxx_test_suite_set_correct();
}
}
void c_take_ref_rust_vec_copy(const rust::Vec<uint8_t> &v) {
// The std::copy() will make sure rust::Vec<>::const_iterator satisfies the
// requirements for std::iterator_traits.

View File

@ -65,9 +65,12 @@ void c_take_unique_ptr_vector_f64(std::unique_ptr<std::vector<double>> v);
void c_take_unique_ptr_vector_shared(std::unique_ptr<std::vector<Shared>> v);
void c_take_ref_vector(const std::vector<uint8_t> &v);
void c_take_rust_vec(rust::Vec<uint8_t> v);
void c_take_rust_vec_index(rust::Vec<uint8_t> v);
void c_take_rust_vec_shared(rust::Vec<Shared> v);
void c_take_rust_vec_shared_index(rust::Vec<Shared> v);
void c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v);
void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v);
void c_take_ref_rust_vec_index(const rust::Vec<uint8_t> &v);
void c_take_ref_rust_vec_copy(const rust::Vec<uint8_t> &v);
/*
// https://github.com/dtolnay/cxx/issues/232

View File

@ -108,15 +108,16 @@ fn test_c_take() {
check!(ffi::c_take_ref_vector(&ffi::c_return_unique_ptr_vector_u8()));
let test_vec = [86_u8, 75_u8, 30_u8, 9_u8].to_vec();
check!(ffi::c_take_rust_vec(test_vec.clone()));
check!(ffi::c_take_rust_vec_shared(vec![
check!(ffi::c_take_rust_vec_index(test_vec.clone()));
let shared_test_vec = vec![
ffi::Shared { z: 1010 },
ffi::Shared { z: 1011 }
]));
check!(ffi::c_take_rust_vec_shared_forward_iterator(vec![
ffi::Shared { z: 1010 },
ffi::Shared { z: 1011 }
]));
];
check!(ffi::c_take_rust_vec_shared(shared_test_vec.clone()));
check!(ffi::c_take_rust_vec_shared_index(shared_test_vec.clone()));
check!(ffi::c_take_rust_vec_shared_forward_iterator(shared_test_vec));
check!(ffi::c_take_ref_rust_vec(&test_vec));
check!(ffi::c_take_ref_rust_vec_index(&test_vec));
check!(ffi::c_take_ref_rust_vec_copy(&test_vec));
check!(ffi::c_take_enum(ffi::Enum::AVal));
}