Skip to content

Commit f846bb6

Browse files
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
1 parent 94e8e46 commit f846bb6

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

include/cxx.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ class Slice final
220220
std::array<std::uintptr_t, 2> repr;
221221
};
222222

223+
// Slice<T> template deduction guides
224+
#ifdef __cpp_deduction_guides
225+
template <typename C>
226+
explicit Slice(C &c)
227+
-> Slice<std::remove_reference_t<decltype(*std::declval<C>().data())>>;
228+
#endif // __cpp_deduction_guides
229+
223230
template <typename T>
224231
class Slice<T>::iterator final {
225232
public:

tests/ffi/tests.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -891,11 +891,36 @@ extern "C" const char *cxx_run_test() noexcept {
891891
rust::String bad_utf16_rstring = rust::String::lossy(bad_utf16_literal);
892892
ASSERT(bad_utf8_rstring == bad_utf16_rstring);
893893

894-
std::vector<int> cpp_vec{1, 2, 3};
895-
rust::Slice<int> slice_of_cpp_vec(cpp_vec);
896-
ASSERT(slice_of_cpp_vec.data() == cpp_vec.data());
897-
ASSERT(slice_of_cpp_vec.size() == cpp_vec.size());
898-
ASSERT(slice_of_cpp_vec[0] == 1);
894+
// Test Slice<T> explicit constructor from container
895+
{
896+
std::vector<int> cpp_vec{1, 2, 3};
897+
rust::Slice<int> slice_of_cpp_vec(cpp_vec);
898+
ASSERT(slice_of_cpp_vec.data() == cpp_vec.data());
899+
ASSERT(slice_of_cpp_vec.size() == cpp_vec.size());
900+
ASSERT(slice_of_cpp_vec[0] == 1);
901+
}
902+
903+
// Test Slice<T> template deduction guides
904+
#ifdef __cpp_deduction_guides
905+
{
906+
// C<T> -> Slice<T>
907+
std::vector<int> cpp_vec{1, 2, 3};
908+
auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec);
909+
static_assert(
910+
std::is_same_v<decltype(auto_slice_of_cpp_vec), rust::Slice<int>>);
911+
ASSERT(auto_slice_of_cpp_vec.data() == cpp_vec.data());
912+
ASSERT(auto_slice_of_cpp_vec.size() == cpp_vec.size());
913+
}
914+
{
915+
// const C<T> -> Slice<const T>
916+
const std::vector<int> cpp_vec{1, 2, 3};
917+
auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec);
918+
static_assert(std::is_same_v<decltype(auto_slice_of_cpp_vec),
919+
rust::Slice<const int>>);
920+
ASSERT(auto_slice_of_cpp_vec.data() == cpp_vec.data());
921+
ASSERT(auto_slice_of_cpp_vec.size() == cpp_vec.size());
922+
}
923+
#endif // __cpp_deduction_guides
899924

900925
rust::Vec<int> vec1{1, 2};
901926
rust::Vec<int> vec2{3, 4};

0 commit comments

Comments
 (0)