mirror of https://github.com/swig/swig.git
162 lines
6.0 KiB
OpenEdge ABL
162 lines
6.0 KiB
OpenEdge ABL
%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>;
|