/
niceSOFT
/
swig
Обзор
Документация
Войти
/
niceSOFT
/
swig
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Examples/test-suite/cpp11_template_using_base.i
161 строка
6 KB
William S Fulton
Detect inheriting constructors by base class match in the parser
17 июн 2026, 03:47
17 июн 2026, 03:47
638742f
Код
Авторство
О чём код?
%module cpp11_template_using_base // Exercises a using-declaration that names a member through a type-template // parameter used directly as the base class. // SWIGWARN_LANG_OVERLOAD_SHADOW: lua only has one numeric type, so the int/double overloads of // call shadow each other. The other warnings suppress per target multiple inheritance notes. %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE, SWIGWARN_RUBY_MULTIPLE_INHERITANCE, SWIGWARN_LANG_OVERLOAD_SHADOW) Overloaded<IntCase, DoubleCase>; %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE, SWIGWARN_RUBY_MULTIPLE_INHERITANCE, SWIGWARN_LANG_OVERLOAD_SHADOW) TypedefChainMultiBase; %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE, SWIGWARN_RUBY_MULTIPLE_INHERITANCE, SWIGWARN_LANG_OVERLOAD_SHADOW) TypedefArgMultiBase; #ifdef SWIGD // D supports single inheritance only. Without this ignore the using-declaration brings call(double) // into the D proxy with an 'override' keyword that has no matching base method, a D compile error. %ignore DoubleCase::call; #endif %include <std_string.i> %inline %{ #include <string> struct IntCase { int seed; IntCase() : seed(0) {} IntCase(int s) : seed(s) {} std::string call(int v) const { return "Int:" + std::to_string(seed + v); } }; struct DoubleCase { double value; DoubleCase(double v = 0.0) : value(v) {} std::string call(double v) const { return "Double:" + std::to_string(v); } }; // Inheriting constructors (using I::I;) and an inherited member (using I::call;) // through a type-template parameter base. See issue #2951. template <typename I> struct Derived : I { using I::I; using I::call; }; %} %template(DerivedInt) Derived<IntCase>; %inline %{ // Inheriting constructors through a typedef-name for a base class that is itself a template instantiation. // The qualifier is a typedef rather than the base class name, and the base's own constructors were inherited. // See issue #2951. struct TypedefMixin : Derived<IntCase> { typedef Derived<IntCase> base_type; using base_type::base_type; }; // As TypedefMixin, but the unqualified-id is the base template's own name (using base_type::Derived). struct TypedefNameMixin : Derived<IntCase> { typedef Derived<IntCase> base_type; using base_type::Derived; }; %} %inline %{ // As above, but the using-declaration qualifier is a typedef of a typedef naming the base class, so resolving it // to the base class requires following a chain of typedefs. struct TypedefChainMixin : Derived<IntCase> { typedef Derived<IntCase> base_alias; typedef base_alias base_type; using base_type::base_type; }; %} %inline %{ // Multiple bases AND a typedef of a typedef naming the base class: resolving the using-declaration // qualifier to the correct base needs the full typedef chain even when there is more than one base, so // the single-base shortcut cannot mask it. See issue #2951. struct TypedefChainMultiBase : DoubleCase, Derived<IntCase> { typedef Derived<IntCase> base_alias; typedef base_alias base_type; using base_type::base_type; // inherits Derived<IntCase>'s (inherited IntCase(int)) constructors using Derived<IntCase>::call; // call(int) so the inherited constructor's seed is observable using DoubleCase::call; // call(double) so the second base is observably present }; %} %inline %{ // Multiple bases where the base is named through a typedef whose template argument is itself a typedef. The // written form Derived<(IntCaseAlias)> differs from the resolved base name Derived<(IntCase)>, so the immediate // base is found by resolving the qualifier to a node and matching by identity, not by its written form. See // issue #2951. typedef IntCase IntCaseAlias; struct TypedefArgMultiBase : DoubleCase, Derived<IntCaseAlias> { typedef Derived<IntCaseAlias> base_type; using base_type::base_type; // inheriting constructor through the typedef-argument base using Derived<IntCase>::call; // call(int) so the inherited constructor's seed is observable using DoubleCase::call; // call(double) so the second base is observably present }; %} %inline %{ // The base is named through a scope-qualified qualifier (ns2951::QualBase), so the inheriting-constructor // unqualified-id 'QualBase' must be matched against the last component of the qualifier, not the whole scope // qualified name. See issue #2951. namespace ns2951 { struct QualBase { int seed; QualBase() : seed(0) {} QualBase(int s) : seed(s) {} std::string call(int v) const { return "Int:" + std::to_string(seed + v); } }; } struct QualifiedBaseUsing : ns2951::QualBase { using ns2951::QualBase::QualBase; }; struct SemiQualifiedBaseUsing : ns2951::QualBase { using QualBase::QualBase; // not fully qualified }; %} %inline %{ // The base is reached through a typedef of a typedef whose intermediate typedef lives in a namespace, so the // inheriting constructor is found by resolving the qualifier through the namespace-scoped chain. See issue #2951. namespace ns2951b { struct NsBase { int seed; NsBase() : seed(0) {} NsBase(int s) : seed(s) {} std::string call(int v) const { return "Int:" + std::to_string(seed + v); } }; } struct NsChainUsing : ns2951b::NsBase { typedef ns2951b::NsBase ns_alias; typedef ns_alias ns_base; using ns_base::ns_base; }; %} %inline %{ template <typename I, typename D> struct Overloaded : I, D { using I::I; using D::D; using I::call; using D::call; }; %} %template(OverloadedIntDouble) Overloaded<IntCase, DoubleCase>;