Author: Wim Lavrijsen <[email protected]>
Branch: cppyy-dev
Changeset: r98049:47555bb4c1cc
Date: 2019-11-13 11:50 -0800
http://bitbucket.org/pypy/pypy/changeset/47555bb4c1cc/
Log: prepare for more template tests
diff --git a/pypy/module/_cppyy/interp_cppyy.py
b/pypy/module/_cppyy/interp_cppyy.py
--- a/pypy/module/_cppyy/interp_cppyy.py
+++ b/pypy/module/_cppyy/interp_cppyy.py
@@ -981,8 +981,8 @@
)
class W_CPPTemplateStaticOverload(W_CPPStaticOverload, TemplateOverloadMixin):
- """App-level dispatcher to allow both lookup/instantiation of templated
methods and
- dispatch among overloads between templated and non-templated method."""
+ """Dispatcher to allow both lookup/instantiation of templated methods and
+ select among templated and non-templated method overloads."""
_attrs_ = ['name', 'tmpl_args', 'overloads', 'master', 'w_this']
_immutable_fields_ = ['name', 'tmpl_args']
@@ -996,7 +996,8 @@
self.w_this = space.w_None
def clone(self, tmpl_args):
- other = W_CPPTemplateStaticOverload(self.space, self.name, tmpl_args,
self.scope, self.functions, self.flags)
+ other = W_CPPTemplateStaticOverload(self.space, self.name,
+ tmpl_args, self.scope, self.functions, self.flags)
other.overloads = self.overloads
other.master = self.master
other.w_this = self.w_this
@@ -1007,7 +1008,8 @@
if isinstance(w_cppinstance, W_CPPInstance):
cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance)
if cppinstance.clsdecl.handle != self.scope.handle:
- cppol = W_CPPTemplateStaticOverload(self.space, self.name,
self.tmpl_args, self.scope, self.functions, self.flags)
+ cppol = W_CPPTemplateStaticOverload(self.space, self.name,
+ self.tmpl_args, self.scope, self.functions, self.flags)
cppol.w_this = w_cppinstance
cppol.master = self.master
return cppol # bound
@@ -1256,10 +1258,10 @@
return self.handle != other.handle
-# For now, keep namespaces and classes separate as namespaces are extensible
+# Namespaces and classes are separate as namespaces are (more) extensible
# with info from multiple dictionaries and do not need to bother with meta
-# classes for inheritance. Both are python classes, though, and refactoring
-# may be in order at some point.
+# classes for inheritance. Both are python classes, though, and further
+# refactoring may be in order at some point.
class W_CPPNamespaceDecl(W_CPPScopeDecl):
_attrs_ = ['space', 'handle', 'name', 'overloads', 'datamembers']
_immutable_fields_ = ['handle', 'name']
diff --git a/pypy/module/_cppyy/test/templates.cxx
b/pypy/module/_cppyy/test/templates.cxx
--- a/pypy/module/_cppyy/test/templates.cxx
+++ b/pypy/module/_cppyy/test/templates.cxx
@@ -10,3 +10,28 @@
long MyTemplatedMethodClass::get_float_size() { return (long)sizeof(float); }
long MyTemplatedMethodClass::get_double_size() { return (long)sizeof(double); }
long MyTemplatedMethodClass::get_self_size() { return
(long)sizeof(MyTemplatedMethodClass); }
+
+
+// variadic templates
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+std::string some_variadic::gTypeName = "";
+
+
+// template with empty body
+namespace T_WithEmptyBody {
+
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+std::string side_effect = "not set";
+
+template<typename T>
+void some_empty() {
+ side_effect = "side effect";
+}
+
+template void some_empty<int>();
+
+} // namespace T_WithRValue
diff --git a/pypy/module/_cppyy/test/templates.h
b/pypy/module/_cppyy/test/templates.h
--- a/pypy/module/_cppyy/test/templates.h
+++ b/pypy/module/_cppyy/test/templates.h
@@ -1,12 +1,33 @@
+#ifndef CPPYY_TEST_TEMPLATES_H
+#define CPPYY_TEST_TEMPLATES_H
+
+#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
+#ifndef WIN32
+#include <cxxabi.h>
+inline std::string demangle_it(const char* name, const char* errmsg) {
+ int status;
+ std::string res = abi::__cxa_demangle(name, 0, 0, &status);
+ if (status != 0) throw std::runtime_error(errmsg);
+ return res;
+}
+#else
+inline std::string demangle_it(const char* name, const char*) {
+ return name; // typeinfo's name() is already demangled
+}
+#endif
+
//===========================================================================
class MyTemplatedMethodClass { // template methods
public:
- long get_size(); // to get around bug in genreflex
+ template<class A> long get_size(A&);
+ template<class A> long get_size(const A&);
+
+ long get_size();
template<class B> long get_size();
long get_char_size();
@@ -21,6 +42,16 @@
double m_data[3];
};
+template<class A>
+long MyTemplatedMethodClass::get_size(A&) {
+ return sizeof(A);
+}
+
+template<class A>
+long MyTemplatedMethodClass::get_size(const A&) {
+ return sizeof(A)+1;
+}
+
template<class B>
inline long MyTemplatedMethodClass::get_size() {
return sizeof(B);
@@ -63,7 +94,7 @@
};
template <class I, typename O = float>
-SomeResult<O> global_get_some_result(const std::vector<I>& carrier) {
+SomeResult<O> global_get_some_result(const I& carrier) {
SomeResult<O> r{};
r.m_retval = O(carrier[0]);
return r;
@@ -156,3 +187,295 @@
T m_value;
};
*/
+
+
+//===========================================================================
+// templated callable
+class TemplatedCallable {
+public:
+ template <class I , class O = double>
+ O operator() (const I& in) const { return O(in); }
+};
+
+
+//===========================================================================
+// templated typedefs
+namespace TemplatedTypedefs {
+
+template<typename TYPE_IN, typename TYPE_OUT, size_t _vsize = 4>
+struct BaseWithEnumAndTypedefs {
+ enum { vsize = _vsize };
+ typedef TYPE_IN in_type;
+ typedef TYPE_OUT out_type;
+};
+
+template <typename TYPE_IN, typename TYPE_OUT, size_t _vsize = 4>
+struct DerivedWithUsing : public BaseWithEnumAndTypedefs<TYPE_IN, TYPE_OUT,
_vsize>
+{
+ typedef BaseWithEnumAndTypedefs<TYPE_IN, TYPE_OUT, _vsize> base_type;
+ using base_type::vsize;
+ using typename base_type::in_type;
+ typedef typename base_type::in_type in_type_tt;
+ using typename base_type::out_type;
+};
+
+struct SomeDummy {};
+
+} // namespace TemplatedTypedefs
+
+
+//===========================================================================
+// hiding templated methods
+namespace TemplateHiding {
+
+struct Base {
+ template<class T>
+ int callme(T t = T(1)) { return 2*t; }
+};
+
+struct Derived : public Base {
+ int callme(int t = 2) { return t; }
+};
+
+} // namespace TemplateHiding
+
+
+//===========================================================================
+// 'using' of templates
+template<typename T> using DA_vector = std::vector<T>;
+
+#if __cplusplus > 201402L
+namespace using_problem {
+
+template <typename T, size_t SZ>
+struct vector {
+ vector() : m_val(SZ) {}
+ T m_val;
+};
+
+template <typename T, size_t ... sizes>
+struct matryoshka {
+ typedef T type;
+};
+
+template <typename T, size_t SZ, size_t ... sizes>
+struct matryoshka<T, SZ, sizes ... > {
+ typedef vector<typename matryoshka<T, sizes ...>::type, SZ> type;
+};
+
+template <typename T, size_t ... sizes>
+using make_vector = typename matryoshka<T, sizes ...>::type;
+ typedef make_vector<int, 2, 3> iiv_t;
+};
+#endif
+
+namespace using_problem {
+
+template<typename T>
+class Base {
+public:
+ template<typename R>
+ R get1(T t) { return t + R{5}; }
+ T get2() { return T{5}; }
+ template<typename R>
+ R get3(T t) { return t + R{5}; }
+ T get3() { return T{5}; }
+};
+
+template<typename T>
+class Derived : public Base<T> {
+public:
+ typedef Base<T> _Mybase;
+ using _Mybase::get1;
+ using _Mybase::get2;
+ using _Mybase::get3;
+};
+
+} // namespace using_problem
+
+
+//===========================================================================
+// template with r-value
+namespace T_WithRValue {
+
+template<typename T>
+bool is_valid(T&& new_value) {
+ return new_value != T{};
+}
+
+} // namespace T_WithRValue
+
+
+//===========================================================================
+// variadic templates
+namespace some_variadic {
+
+#ifdef WIN32
+extern __declspec(dllimport) std::string gTypeName;
+#else
+extern std::string gTypeName;
+#endif
+
+template <typename ... Args>
+class A {
+public:
+ A() {
+ gTypeName = demangle_it(typeid(A<Args...>).name(), "A::A");
+ }
+ A(const A&) = default;
+ A(A&&) = default;
+ A& operator=(const A&) = default;
+ A& operator=(A&&) = default;
+
+ template <typename ... FArgs>
+ void a(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(&A<Args...>::a<FArgs...>).name(),
"A::a-2");
+ }
+
+ template <typename T, typename ... FArgs>
+ T a_T(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(&A<Args...>::a_T<T, FArgs...>).name(),
"A::a_T-2");
+ return T{};
+ }
+
+ template <typename ... FArgs>
+ static void sa(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(A<Args...>).name(), "A::sa-1");
+ gTypeName += "::";
+ gTypeName += demangle_it(typeid(A<Args...>::sa<FArgs...>).name(),
"A::sa-2");
+ }
+
+ template <typename T, typename ... FArgs>
+ static T sa_T(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(A<Args...>).name(), "A::sa_T-1");
+ gTypeName += "::";
+ gTypeName += demangle_it(typeid(A<Args...>::sa_T<T, FArgs...>).name(),
"A::sa_T-2");
+ return T{};
+ }
+};
+
+class B {
+public:
+ B() {
+ gTypeName = demangle_it(typeid(B).name(), "B::B");
+ }
+ B(const B&) = default;
+ B(B&&) = default;
+ B& operator=(const B&) = default;
+ B& operator=(B&&) = default;
+
+ template <typename ... FArgs>
+ void b(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(&B::b<FArgs...>).name(), "B::b-2");
+ }
+
+ template <typename T, typename ... FArgs>
+ T b_T(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(&B::b_T<T, FArgs...>).name(),
"B::b_T-2");
+ return T{};
+ }
+
+ template <typename ... FArgs>
+ static void sb(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(B).name(), "B::sb-1");
+ gTypeName += "::";
+ gTypeName += demangle_it(typeid(B::sb<FArgs...>).name(), "B::sb-2");
+ }
+
+ template <typename T, typename ... FArgs>
+ static T sb_T(FArgs&&... args) {
+ gTypeName = demangle_it(typeid(B).name(), "B::sb_T-1");
+ gTypeName += "::";
+ gTypeName += demangle_it(typeid(B::sb_T<T, FArgs...>).name(),
"B::sb_T-2");
+ return T{};
+ }
+};
+
+template <typename ... Args>
+void fn(Args&&... args) {
+ gTypeName = demangle_it(typeid(fn<Args...>).name(), "fn");
+}
+
+template <typename T, typename ... Args>
+T fn_T(Args&&... args) {
+ gTypeName = demangle_it(typeid(fn<Args...>).name(), "fn_T");
+ return T{};
+}
+
+} // namespace some_variadic
+
+
+//===========================================================================
+// template with empty body
+namespace T_WithEmptyBody {
+
+#ifdef WIN32
+extern __declspec(dllimport) std::string side_effect;
+#else
+extern std::string side_effect;
+#endif
+
+template<typename T>
+void some_empty();
+
+} // namespace T_WithEmptyBody
+
+
+//===========================================================================
+// template with catch-all (void*, void**)overloads
+namespace T_WithGreedyOverloads {
+
+class SomeClass {
+ double fD;
+};
+
+class WithGreedy1 {
+public:
+ template<class T>
+ int get_size(T*) { return (int)sizeof(T); }
+ int get_size(void*, bool force=false) { return -1; }
+};
+
+class WithGreedy2 {
+public:
+ template<class T>
+ int get_size(T*) { return (int)sizeof(T); }
+ int get_size(void**, bool force=false) { return -1; }
+};
+
+class DoesNotExist;
+
+class WithGreedy3 {
+public:
+ template<class T>
+ int get_size(T*) { return (int)sizeof(T); }
+ int get_size(DoesNotExist*, bool force=false) { return -1; }
+};
+
+} // namespace T_WithGreedyOverloads
+
+
+//===========================================================================
+// template with overloaded non-templated and templated setitem
+namespace TemplateWithSetItem {
+
+template <typename T>
+class MyVec {
+private:
+ std::vector<T> fData;
+
+public:
+ using size_type = typename std::vector<T>::size_type;
+
+ MyVec(size_type count) : fData(count) {}
+
+ T & operator[](size_type index) { return fData[index]; }
+
+ // The definition of this templated operator causes the issue
+ template <typename V>
+ MyVec operator[](const MyVec<V> &conds) const { return MyVec(2); }
+};
+
+} // namespace TemplateWithSetItem
+
+#endif // !CPPYY_TEST_TEMPLATES_H
diff --git a/pypy/module/_cppyy/test/templates.xml
b/pypy/module/_cppyy/test/templates.xml
--- a/pypy/module/_cppyy/test/templates.xml
+++ b/pypy/module/_cppyy/test/templates.xml
@@ -16,4 +16,21 @@
<function name="SomeNS::some_bar" />
<function name="SomeNS::tuplify" />
+ <class name="TemplatedCallable" />
+
+ <namespace name="TemplateHiding" />
+ <class pattern="TemplateHiding::*" />
+
+ <namespace name="using_problem" />
+
+ <namespace name="some_variadic" />
+ <class pattern="some_variadic::*" />
+ <function pattern="some_variadic::*" />
+ <variable pattern="some_variadic::*" />
+
+ <namespace name="T_WithEmptyBody" />
+
+ <namespace name="T_WithGreedyOverloads" />
+ <class pattern="T_WithGreedyOverloads::*" />
+
</lcgdict>
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit