Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ set(PYBIND11_TEST_FILES
test_stl
test_stl_binders
test_tagbased_polymorphic
test_template_alias_base
test_thread
test_union
test_virtual_functions)
Expand Down
24 changes: 24 additions & 0 deletions tests/test_template_alias_base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "pybind11_tests.h"

#include <memory>

template <class T>
using DefaultAllocator = std::allocator<T>;

template <template <class> class Allocator = DefaultAllocator>
struct Base {};

template <template <class> class Allocator = DefaultAllocator>
struct S : public Base<Allocator> {};

// this returns S<DefaultAllocator> even though we register
// the type S<std::allocator>
// MSVC and Clang on Windows failed here to detect the registered type
S<> make_S() { return S<>{}; }
Copy link
Collaborator

@rwgk rwgk Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically stress-testing the compiler+library: can it figure out that S<DefaultAllocator> and S<std::allocator> are the same?

Question 1: Is it difficult to not have that stress-test baked into your downstream project? Either, by consistently avoiding the alias, or consistently using the alias.

Question 2: What happens if you patch internals.h similar to #4319?

If you decide to experiment more here, could you please not force push? That makes it more difficult for me to follow.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically stress-testing the compiler+library: can it figure out that S and Sstd::allocator are the same?

Correct.

Question 1: Is it difficult to not have that stress-test baked into your downstream project? Either, by consistently avoiding the alias, or consistently using the alias.

This is somewhat tricky in my case, especially across library/module interfaces. By consistently using one or the other, one has to hope a user does never use the other possible option of the alias.

Question 2: What happens if you patch internals.h similar to #4319?

Will try and push here.

If you decide to experiment more here, could you please not force push? That makes it more difficult for me to follow.

Will do! I just force-pushed initially yesterday when I realized the initial test draft was not yet complete/buggy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed patch :)

Copy link
Collaborator Author

@ax3l ax3l Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rwgk I don't understand your patch yet:
The comment says, GNU's libstdc++ is good (#if defined(__GLIBCXX__)) - all other implementations need the self-made hash.

Your patch says LLVM's libc++ is not good (#if !defined(_LIBCPP_VERSION)) - but all other implementations can use the standard hashes.

Copy link
Collaborator

@rwgk rwgk Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes: the CI for #4319 that ran yesterday (all successful) supports "LLVM's libc++ is not good (#if !defined(_LIBCPP_VERSION)) - but all other implementations can use the standard hashes."

But it looks like your added test doesn't work universally any way you tried, is that a correct summary?

Copy link
Collaborator Author

@ax3l ax3l Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

My test works on Linux & Windows with libstdc++.


TEST_SUBMODULE(template_alias_base, m) {
py::class_<Base<std::allocator>>(m, "B_std").def(py::init());
py::class_<S<std::allocator>, Base<std::allocator>>(m, "S_std").def(py::init());

m.def("make_S", &make_S);
}
11 changes: 11 additions & 0 deletions tests/test_template_alias_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from pybind11_tests import template_alias_base as m


def test_can_create_variable():
v = m.S_std()
print(v)


def test_can_return_variable():
v = m.make_S()
print(v)