1 #pragma once 2 #include <utility> 3 4 #include "pybind11_tests.h" 5 6 /// Simple class used to test py::local: 7 template <int> class LocalBase { 8 public: LocalBase(int i)9 explicit LocalBase(int i) : i(i) { } 10 int i = -1; 11 }; 12 13 /// Registered with py::module_local in both main and secondary modules: 14 using LocalType = LocalBase<0>; 15 /// Registered without py::module_local in both modules: 16 using NonLocalType = LocalBase<1>; 17 /// A second non-local type (for stl_bind tests): 18 using NonLocal2 = LocalBase<2>; 19 /// Tests within-module, different-compilation-unit local definition conflict: 20 using LocalExternal = LocalBase<3>; 21 /// Mixed: registered local first, then global 22 using MixedLocalGlobal = LocalBase<4>; 23 /// Mixed: global first, then local 24 using MixedGlobalLocal = LocalBase<5>; 25 26 /// Registered with py::module_local only in the secondary module: 27 using ExternalType1 = LocalBase<6>; 28 using ExternalType2 = LocalBase<7>; 29 30 using LocalVec = std::vector<LocalType>; 31 using LocalVec2 = std::vector<NonLocal2>; 32 using LocalMap = std::unordered_map<std::string, LocalType>; 33 using NonLocalVec = std::vector<NonLocalType>; 34 using NonLocalVec2 = std::vector<NonLocal2>; 35 using NonLocalMap = std::unordered_map<std::string, NonLocalType>; 36 using NonLocalMap2 = std::unordered_map<std::string, uint8_t>; 37 38 39 // Exception that will be caught via the module local translator. 40 class LocalException : public std::exception { 41 public: LocalException(const char * m)42 explicit LocalException(const char * m) : message{m} {} what()43 const char * what() const noexcept override {return message.c_str();} 44 private: 45 std::string message = ""; 46 }; 47 48 // Exception that will be registered with register_local_exception_translator 49 class LocalSimpleException : public std::exception { 50 public: LocalSimpleException(const char * m)51 explicit LocalSimpleException(const char * m) : message{m} {} what()52 const char * what() const noexcept override {return message.c_str();} 53 private: 54 std::string message = ""; 55 }; 56 57 PYBIND11_MAKE_OPAQUE(LocalVec); 58 PYBIND11_MAKE_OPAQUE(LocalVec2); 59 PYBIND11_MAKE_OPAQUE(LocalMap); 60 PYBIND11_MAKE_OPAQUE(NonLocalVec); 61 //PYBIND11_MAKE_OPAQUE(NonLocalVec2); // same type as LocalVec2 62 PYBIND11_MAKE_OPAQUE(NonLocalMap); 63 PYBIND11_MAKE_OPAQUE(NonLocalMap2); 64 65 66 // Simple bindings (used with the above): 67 template <typename T, int Adjust = 0, typename... Args> bind_local(Args &&...args)68py::class_<T> bind_local(Args && ...args) { 69 return py::class_<T>(std::forward<Args>(args)...) 70 .def(py::init<int>()) 71 .def("get", [](T &i) { return i.i + Adjust; }); 72 }; 73 74 // Simulate a foreign library base class (to match the example in the docs): 75 namespace pets { 76 class Pet { 77 public: Pet(std::string name)78 explicit Pet(std::string name) : name_(std::move(name)) {} 79 std::string name_; name()80 const std::string &name() const { return name_; } 81 }; 82 } // namespace pets 83 MixGLMixGL84struct MixGL { int i; explicit MixGL(int i) : i{i} {} }; MixGL2MixGL285struct MixGL2 { int i; explicit MixGL2(int i) : i{i} {} }; 86