From f846bb6b912ab599ba6afe93c7cad859cec23f84 Mon Sep 17 00:00:00 2001 From: Jonathon Reinhart Date: Thu, 27 Feb 2025 06:49:36 +0000 Subject: [PATCH] Add template deduction guide for Slice constructor PR #1367 added an explicit Slice constructor which allows constructing from any C++ container. This adds a template deduction guide for that constructor which allows the Slice type to be inferred from the container's contained type. This applies to C++17 only. Note that, because C can be any type of container, we need to use a template template parameter. Test: cargo test Test: cargo test -F c++14 Test: cargo test -F c++17 Test: cargo test -F c++20 --- include/cxx.h | 7 +++++++ tests/ffi/tests.cc | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/include/cxx.h b/include/cxx.h index 9d638951e..415dece5e 100644 --- a/include/cxx.h +++ b/include/cxx.h @@ -220,6 +220,13 @@ class Slice final std::array repr; }; +// Slice template deduction guides +#ifdef __cpp_deduction_guides +template +explicit Slice(C &c) + -> Slice().data())>>; +#endif // __cpp_deduction_guides + template class Slice::iterator final { public: diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc index a473a046f..6dac0efb6 100644 --- a/tests/ffi/tests.cc +++ b/tests/ffi/tests.cc @@ -891,11 +891,36 @@ extern "C" const char *cxx_run_test() noexcept { rust::String bad_utf16_rstring = rust::String::lossy(bad_utf16_literal); ASSERT(bad_utf8_rstring == bad_utf16_rstring); - std::vector cpp_vec{1, 2, 3}; - rust::Slice slice_of_cpp_vec(cpp_vec); - ASSERT(slice_of_cpp_vec.data() == cpp_vec.data()); - ASSERT(slice_of_cpp_vec.size() == cpp_vec.size()); - ASSERT(slice_of_cpp_vec[0] == 1); + // Test Slice explicit constructor from container + { + std::vector cpp_vec{1, 2, 3}; + rust::Slice slice_of_cpp_vec(cpp_vec); + ASSERT(slice_of_cpp_vec.data() == cpp_vec.data()); + ASSERT(slice_of_cpp_vec.size() == cpp_vec.size()); + ASSERT(slice_of_cpp_vec[0] == 1); + } + + // Test Slice template deduction guides +#ifdef __cpp_deduction_guides + { + // C -> Slice + std::vector cpp_vec{1, 2, 3}; + auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec); + static_assert( + std::is_same_v>); + ASSERT(auto_slice_of_cpp_vec.data() == cpp_vec.data()); + ASSERT(auto_slice_of_cpp_vec.size() == cpp_vec.size()); + } + { + // const C -> Slice + const std::vector cpp_vec{1, 2, 3}; + auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec); + static_assert(std::is_same_v>); + ASSERT(auto_slice_of_cpp_vec.data() == cpp_vec.data()); + ASSERT(auto_slice_of_cpp_vec.size() == cpp_vec.size()); + } +#endif // __cpp_deduction_guides rust::Vec vec1{1, 2}; rust::Vec vec2{3, 4};