mirror of https://github.com/swig/swig
Added support for the D programming languge.
It is still a bit rough around some edges, particularly with regard to multi-threading and operator overloading, and there are some documentation bits missing, but it should be fine for basic use. The test-suite should build and run fine with the current versions of DMD, LDC and Tango (at least) on Linux x86_64 and Mac OS X 10.6. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12299 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a355d2d46a
commit
03aefbc6e9
|
@ -0,0 +1,401 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG and D</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<H1><a name="D"></a>20 SWIG and D</H1>
|
||||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#D_introduction">Introduction</a>
|
||||
<li><a href="#D_command_line_invocation">Command line invocation</a>
|
||||
<li><a href="#D_typemaps">Typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#D_typemap_name_comparison">C# <-> D name comparison</a>
|
||||
<li><a href="#D_cwtype_dwtype_dptype">cwtype, dwtype, dptype</a>
|
||||
<li><a href="#D_in_out_directorin_direcetorout">in, out, directorin, directorout</a>
|
||||
<li><a href="#D_din_dout_ddirectorin_ddirectorout">din, dout, ddirectorin, ddirectorout</a>
|
||||
<li><a href="#D_typecheck_typemaps">typecheck typemaps</a>
|
||||
<li><a href="#D_code_injection_typemaps">Code injection typemaps</a>
|
||||
<li><a href="#D_special_variables">Special variable macros</a>
|
||||
</ul>
|
||||
<li><a href="#D_features"><tt>%feature</tt>s</a>
|
||||
<li><a href="#D_pragmas">Pragmas</a>
|
||||
<li><a href="#D_exceptions">D Exceptions</a>
|
||||
<li><a href="#D_directors">D Directors</a>
|
||||
<li><a href="#D_other_features">Other features</a>
|
||||
<li><a href="#D_typemap_examples">D Typemap examples</a>
|
||||
<li><a href="#D_planned_features">Work in progress and planned features</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<H2><a name="D_introduction"></a>20.1 Introduction</H2>
|
||||
|
||||
|
||||
<p>From the <a href="http://www.digitalmars.com/d/">D Programming Language</a> web site: <em>»D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. […] The D language is statically typed and compiles directly to machine code.«</em> As such, it is not very surprising that D is able to directly <a href="http://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
|
||||
|
||||
<p>Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to <tt>\0</tt>-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.</p>
|
||||
|
||||
<p>While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. D did not support interfacing to C++ in version 1 at all, and even if <tt>extern(C++)</tt> has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases. </p>
|
||||
|
||||
<p>To help addressing these issues, the SWIG C# module has been forked to support D. Is has evolved quite a lot since then, but there are still many similarities, so if you do not find what you are looking for on this page, it might be worth having a look at the chapter on <a href="CSharp.html">C#</a> (and also on <a href="Java.html">Java</a>, since the C# module was in turn forked from it).</p>
|
||||
|
||||
|
||||
<H2><a name="D_command_line_invocation"></a>20.2 Command line invocation</H2>
|
||||
|
||||
|
||||
<p>To activate the D module, pass the <tt>-d</tt> option to SWIG at the command line. The same standard command line switches as with any other language module are available, plus the following D specific ones:</p>
|
||||
|
||||
<dl>
|
||||
<dt id="D_splitproxy"><tt>-splitproxy</tt></dt>
|
||||
<dd>
|
||||
<p>By default, SWIG generates two D modules: the <em>proxy</em> module, named like the source module (either specified via the <tt>%module</tt> directive or via the <tt>module</tt> command line switch), which contains all the proxy classes, functions, enums, etc., and the <em>wrap</em> module (named like the proxy module, but suffixed with <tt>_wrap</tt>), which contains all the <tt>extern(C)</tt> function declarations and other private parts only used internally by the proxy module.</p>
|
||||
<p>If the split proxy mode is enabled by passing this switch at the command line, all proxy classes and enums are emitted to their own D module instead. The main proxy module only contains free functions and constants in this case.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>-package <pkg></tt></dt>
|
||||
<dd>
|
||||
<p>By default, the proxy D modules and the wrap D module are written to the root package. Using this option, you can specify another target package instead.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>-wrapperlibrary <wl></tt></dt>
|
||||
<dd>
|
||||
<p>The code SWIG generates to dynamically load the C/C++ wrapper layer looks for a library called <tt>$module_wrap</tt>, just like the wrap D module is. With this switch, you can override the name of the file the wrapper code loads at runtime (the <tt>lib</tt> prefix and the suffix for shared libraries are appended automatically, depending on the OS).</p>
|
||||
<p>This might especially be useful if you want to invoke SWIG several times on separate modules, but compile the resulting code into a single shared library.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<H2><a name="D_typemaps"></a>20.3 Typemaps</H2>
|
||||
|
||||
|
||||
<H3><a name="D_typemap_name_comparison"></a>20.3.1 C# <-> D name comparison</H3>
|
||||
|
||||
|
||||
<div class="diagram"><pre>
|
||||
ctype <-> cwtype
|
||||
imtype <-> dwtype
|
||||
cstype <-> dptype
|
||||
csin <-> din
|
||||
csout <-> dout
|
||||
csdirectorin <-> ddirectorin
|
||||
csdirectorout <-> ddirectorout
|
||||
csinterfaces <-> dinterfaces
|
||||
csinterfaces_derived <-> dinterfaces_derived
|
||||
csbase <-> dbase
|
||||
csclassmodifiers <-> dclassmodifiers
|
||||
cscode <-> dcode
|
||||
csimports <-> dimports
|
||||
csbody <-> dbody
|
||||
csfinalize <-> ddestructor
|
||||
csdestruct <-> ddispose
|
||||
csdestruct_derived <-> ddispose_derived
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="D_cwtype_dwtype_dptype"></a>20.3.2 cwtype, dwtype, dptype</H3>
|
||||
|
||||
|
||||
<p>Mapping of types between the C/C++ library, the C/C++ library wrapper exposing the C functions, the D wrapper module importing these functions and the D proxy code.</p>
|
||||
|
||||
<p>The <tt>cwtype</tt> typemap is used to determine the types to use in the C wrapper functions. The types from the <tt>dwtype</tt> typemap are used in the extern(C) declarations of these functions in the D wrap module. The <tt>dptype</tt> typemap contains the D types used in the D proxy module/class.</p>
|
||||
|
||||
|
||||
<H3><a name="D_in_out_directorin_direcetorout"></a>20.3.3 in, out, directorin, directorout</H3>
|
||||
|
||||
|
||||
<p>Used for converting between the types for C/C++ and D when generating the code for the wrapper functions (on the C++ side).</p>
|
||||
|
||||
<p>The code from the <tt>in</tt> typemap is used to convert arguments to the C wrapper function to the type used in the wrapped code (<tt>cwtype</tt>->original C++ type), the <tt>out</tt> typemap is utilized to convert values from the wrapped code to wrapper function return types (original C++ type-><tt>cwtype</tt>).</p>
|
||||
|
||||
<p>The <tt>directorin</tt> typemap is used to convert parameters to the type used in the D director callback function, its return value is processed by <tt>directorout</tt> (see below).</p>
|
||||
|
||||
|
||||
<H3><a name="D_din_dout_ddirectorin_ddirectorout"></a>20.3.4 din, dout, ddirectorin, ddirectorout</H3>
|
||||
|
||||
|
||||
<p>Typemaps for code generation in D proxy and type wrapper classes.</p>
|
||||
|
||||
<p id="D_din">The <tt>din</tt> typemap is used for converting function parameter types from the type used in the proxy module or class to the type used in the D wrap module (the <a href="D.html#D_dinput"><tt>$dinput</tt></a> macro is replaced).</p>
|
||||
|
||||
<p id="D_dout">The <tt>dout</tt> typemap is used for converting function return values from the return type used in the wrap D module to the type returned by the proxy function. The <tt>$excode</tt> special variable in <tt>dout</tt> typemaps is replaced by the <tt>excode</tt> typemap attribute code if the method can throw any exceptions from unmanaged code, otherwise by nothing (the <a href="D.html#D_wcall"><tt>$wcall</tt> and <tt>$owner</tt></a> macros are replaced).</p>
|
||||
|
||||
<p id="D_ddirectorinout">The code from the <tt>ddirectorin</tt> and <tt>ddirectorout</tt> typemaps is used for conversion in director callback functions. Arguments are converted to the type used in the proxy class method they are calling by using the code from <tt>ddirectorin</tt>, the proxy class method return value is converted to the type the C++ code expects via the <tt>ddirectorout</tt> typemap (the <a href="D.html#D_dpcall"><tt>$dpcall</tt> and <tt>$winput</tt></a> macros are replaced).</p>
|
||||
|
||||
<p>The full chain of type conversions when a director callback is invoked looks like this:</p>
|
||||
|
||||
<div class="diagram"><pre> type CPPClass::method(type a)
|
||||
↑ ↓
|
||||
<directorout> <directorin>
|
||||
↑ ↓
|
||||
cwtype methodCallback(cwtype a) C++
|
||||
::::::::::::::::::::::::::::::::::::::::::
|
||||
dwtype methodCallback(dwtype a) D
|
||||
↑ ↓
|
||||
<ddirectorout> <ddirectorin>
|
||||
↑ ↓
|
||||
dptype DClass.method(dptype a)</pre></div>
|
||||
|
||||
|
||||
<H3><a name="D_typecheck_typemaps"></a>20.3.5 typecheck typemaps</H3>
|
||||
|
||||
|
||||
<p>Because, unlike many scripting languages supported by SWIG, D does not need any dynamic dispatch helper to access an overloaded function, the purpose of these is merely to issue a warning for overloaded C++ functions that cannot be overloaded in D (as more than one C++ type maps to a single D type).</p>
|
||||
|
||||
|
||||
<H3><a name="D_code_injection_typemaps"></a>20.3.6 Code injection typemaps</H3>
|
||||
|
||||
|
||||
<p>These typemaps are used for generating the skeleton of proxy classes for C++ types.</p>
|
||||
|
||||
<p>By overriding <tt>dbase</tt>, <tt>dinterfaces</tt> or <tt>dinterfaces_derived</tt>, the inheritance chain of the generated proxy class for a type can be modified. <tt>dclassmodifiers</tt> allows you to add any custom modifiers around the class keyword.</p>
|
||||
|
||||
<p>Using <tt>dcode</tt> and <tt>dimports</tt>, you can specify additional D code which will be emitted into the class body respectively the imports section of the D module the class is written to.</p>
|
||||
|
||||
<p id="D_class_code_typemaps"><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p>
|
||||
|
||||
|
||||
<H3><a name="D_special_variables"></a>20.3.7 Special variable macros</H3>
|
||||
|
||||
|
||||
<p>The standard SWIG special variables are available for use within typemaps as described in the <a href="Typemaps.html#Typemaps">Typemaps documentation</a>, for example <tt>$1</tt>, <tt>$input</tt>, <tt>$result</tt> etc.</p>
|
||||
|
||||
<p>When generating D wrappers, a few additional macros are available:</p>
|
||||
<dl>
|
||||
<dt><tt>$dclassname</tt> (C#: <tt>$csclassname</tt>)</dt>
|
||||
<dd>
|
||||
<p>This special variable works similar to <a href="Typemaps.html#Typemaps_special_variables"><tt>$n_type</tt></a> in that it returns the name of a type – it expands to the D proxy class name of the type being wrapped. If the type does not have an associated proxy class, it expands to the type wrapper class name, for example, <tt>SWIGTYPE_p_p_SomeCppClass</tt> is generated when wrapping <tt>SomeCppClass **</tt>.</p>
|
||||
<p>There are two other variants available, <tt>$&dclassname</tt> and <tt>$*dclassname</tt>. The former adds a level of indirection, while the latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>$*dclassname</tt> would be replaced by the proxy class name corresponding to <tt>Foo *</tt>.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>$null</tt></dt>
|
||||
<dd><p>In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either <tt>0</tt> or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (<tt>return $null;</tt>).</p></dd>
|
||||
|
||||
<dt id="D_dinput"><tt>$dinput</tt> (C#: <tt>$csinput</tt>)</dt>
|
||||
<dd>
|
||||
<p>This variable is used in <tt><a href="D.html#D_din">din</a></tt> typemaps and is replaced by the expression which is to be passed to C/C++.</p>
|
||||
<p>For example, this input</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(din) SomeClass * "SomeClass.getCPointer($dinput)"
|
||||
|
||||
%inline %{
|
||||
class SomeClass {};
|
||||
void foo(SomeClass *arg);
|
||||
%}</pre></div>
|
||||
<p>leads to the following D proxy code being generated:</p>
|
||||
<div class="targetlang"><pre>
|
||||
void foo(SomeClass arg) {
|
||||
example_wrap.foo(SomeClass.getCPointer(arg));
|
||||
}</pre></div></dd>
|
||||
|
||||
<dt id="D_wcall"><tt>$wcall</tt> and <tt>$owner</tt> (C#: <tt>$imcall</tt>)</dt>
|
||||
<dd>
|
||||
<p>These variables are used in <tt><a href="D.html#D_dout">dout</a></tt> typemaps. <tt>$wcall</tt> contains the call to the wrapper layer which provides the value to be used, and <tt>$owner</tt> signals if the caller is responsible for managing the object lifetime (that is, if the called method is a constructor or has been marked via <tt>%newobject</tt>).</p>
|
||||
<p>Consider the following example:</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(dout) SomeClass * {
|
||||
return new SomeClass($wcall, $owner);
|
||||
}
|
||||
|
||||
%inline %{
|
||||
class SomeClass;
|
||||
SomeClass *foo();
|
||||
|
||||
%newobject bar();
|
||||
SomeClass *bar();
|
||||
%}</pre></div>
|
||||
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
|
||||
<div class="targetlang"><pre>
|
||||
SomeClass foo() {
|
||||
return new SomeClass(example_wrap.foo(), false);
|
||||
}
|
||||
|
||||
SomeClass bar() {
|
||||
return new SomeClass(example_wrap.bar(), true);
|
||||
}
|
||||
</pre></div>
|
||||
</dd>
|
||||
|
||||
<dt><tt>$dpcall</tt> and <tt>$winput</tt> (C#: <tt>$cscall</tt>, <tt>$iminput</tt>)</dt>
|
||||
<dd id="D_dpcall"><p>These variables are used in the director-specific typemaps <a href="D.html#D_ddirectorinout"><tt>ddirectorin</tt></a> and <a href="D.html#D_ddirectorinout"><tt>ddirectorout</tt></a>. They are more or less the reverse of the <tt>$wcall</tt> and <tt>$dinput</tt> macros: <tt>$dpcall</tt> contains the invocation of the D proxy method of which the return value is to be passed back to C++, <tt>$winput</tt> contains the parameter value from C++.</p></dd>
|
||||
|
||||
<dt><tt>$excode</tt></dt>
|
||||
<dd><p>This variable is used in <tt>dout</tt> and <tt>dconstructor</tt> typemaps and is filled with the contents of the <tt>excode</tt> typemap attribute if an exception could be thrown from the C++ side. See the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for details.</p></dd>
|
||||
|
||||
<dt><tt>$dbaseclass</tt></dt>
|
||||
<dd><p>Currently for internal use only, it contains the D name of the C++ base class (if any) inside proxy classes.</p></dd>
|
||||
|
||||
<dt><tt>$directorconnect</tt></dt>
|
||||
<dd>
|
||||
<p>This macro is only valid inside the <tt><a href="D.html#D_class_code_typemaps">dconstructor</a></tt> typemap and contains the value of the <tt>dconstructor</tt> typemap attribute if the currently wrapped class has directors enabled.</p>
|
||||
<p>This is how the default <tt>dconstructor</tt> typemap looks like (you usually do not want to specify a custom one):</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(dconstructor, excode=SWIGEXCODE,directorconnect="\n swigDirectorConnect();") SWIGTYPE {
|
||||
this($wcall, true);$excode$directorconnect
|
||||
}
|
||||
</pre></div>
|
||||
</dd>
|
||||
|
||||
<dt id="D_importtype"><tt>$importtype(SomeDType)</tt></dt>
|
||||
<dd>
|
||||
<p>This macro is used in the <tt>dimports</tt> typemap if a dependency on another D type generated by SWIG is added by a custom typemap.</p>
|
||||
<p>Consider the following code snippet:</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
|
||||
</pre></div>
|
||||
<p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt> to the base class list of <tt>SomeClass</tt>:</p>
|
||||
<div class="targetlang"><pre>
|
||||
class SomeClass : AnInterface, AnotherInterface {
|
||||
…
|
||||
}
|
||||
</pre></div>
|
||||
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
|
||||
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(dimports) RemoteMpe %{
|
||||
$importtype(AnInterface)
|
||||
$importtype(AnotherInterface)
|
||||
%}
|
||||
</pre></div>
|
||||
<p>If SWIG is in split proxy mode, it expands to an <tt>import</tt> statement for the specified type, to nothing if not.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>$module</tt></dt>
|
||||
<dd><p>Expands to the name of the main proxy D module.</p></dd>
|
||||
|
||||
<dt><tt>$wrapdmodule</tt></dt>
|
||||
<dd><p>Contains the fully qualified name of the wrap D module.</p></dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<H2><a name="D_features"></a>20.4 <tt>%feature</tt>s</H2>
|
||||
|
||||
|
||||
<p>The D module defines a number of directives which modify the <a href="Customization.html#Customization_features">SWIG features</a> set globally or for a specific declaration:</p>
|
||||
|
||||
|
||||
<dl>
|
||||
<dt><tt>%dnativeconst</tt> and <tt>%dconstvalue(value)</tt></dt>
|
||||
<dd>
|
||||
<p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt> and C++ constants. The <tt>%dnativeconst</tt> directive enables wrapping these constants as D manifest constants (<tt>const</tt> in D1, <tt>enum</tt> in D2).</p>
|
||||
<p>For this to work, the C/C++ code for the constant value must directly compile as D code, though. If this is not the case, you can manually override the expression written to the D wrapper using the <tt>%dconstvalue</tt> directive, passing the new value as parameter.</p>
|
||||
<p>For <tt>enum</tt>s, again <tt>%dconstvalue</tt> can be used to override the value of an enum item if the initializer should not compile in D.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>%dmethodmodifiers</tt></dt>
|
||||
<dd>
|
||||
<p>This directive can be used to override the modifiers for a proxy function. For instance, you could make a <tt>public</tt> C++ member function <tt>private</tt> in D like this:</p>
|
||||
<div class="code"><pre>
|
||||
%dmethodmodifiers A::foo "private";
|
||||
|
||||
%inline %{
|
||||
struct A {
|
||||
void foo();
|
||||
};
|
||||
%}
|
||||
</pre></div>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<H2><a name="D_pragmas"></a>20.5 Pragmas</H2>
|
||||
|
||||
|
||||
<p>There are a few SWIG pragmas specific to the D module, which you can use to influence the D code SWIG generates:</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt>%pragma(d) wrapdmodulecode</tt></dt>
|
||||
<dd><p>The passed text (D code) is copied verbatim to the wrap D module. For example, it can be (and is, internally) used to emit additional private helper code for the use by proxy typemaps.</p></dd>
|
||||
|
||||
<dt><tt>%pragma(d) wrapdmoduleimports</tt></dt>
|
||||
<dd><p>Additional code to be emitted to the imports section of the wrap D module (the <a href="D.html#D_importtype">$importtype</a> macro can be used here). You probably want to use this in conjunction with the <tt>wrapdmodulecode</tt> pragma.</p></dd>
|
||||
|
||||
<dt><tt>%pragma(d) proxydmodulecode</tt></dt>
|
||||
<dd><p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the proxy D module (if SWIG is in <a href="D.html#D_splitproxy">split proxy mode</a>, it is emitted to the main proxy D module only).</p></dd>
|
||||
|
||||
<dt><tt>%pragma(d) globalproxyimports</tt></dt>
|
||||
<dd>
|
||||
<p>The D module currently does not support specifying dependencies on external modules (e.g. from the standard library) for the D typemaps. To add the import statements to the proxy modules (resp. to <em>all</em> proxy modules if in split proxy mode), you can use the <tt>globalproxyimports</tt> directive.</p>
|
||||
<p>For example:</p>
|
||||
<div class="code"><pre>
|
||||
%typemap(din) char[] "($dinput ? tango.stdc.stringz.toStringz($dinput) : null)"
|
||||
%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
|
||||
</pre></div>
|
||||
</dd>
|
||||
|
||||
<dt><tt>%pragma(d) wrapperloadercode</tt></dt>
|
||||
<dd>
|
||||
<p>The D code for loading the wrapper library (it is copied to the wrap D module). The <tt>$wrapperloaderbindcode</tt> variable is replaced by the list of commands for binding the functions from the wrapper library to the symbols in the wrap D module.</p>
|
||||
<p>Each time this pragma is specified, the previous value is overwritten.</p>
|
||||
</dd>
|
||||
|
||||
<dt><tt>%pragma(d) wrapperloaderbindcommand</tt></dt>
|
||||
<dd>
|
||||
<p>The D command to use for binding the wrapper functions from the C/C++ library to the symbols in the wrap D module. The <tt>$function</tt> variable contains the name of the D function in the wrap module, the <tt>$symbol</tt> variable is replaced by the name of the symbol in the library.</p>
|
||||
<p>Each time this pragma is specified, the previous value is overwritten.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<H2><a name="D_exceptions"></a>20.6 D Exceptions</H2>
|
||||
|
||||
|
||||
<p>Out of the box, C++ exceptions are fundamentally incompatible to their equivalent in the D world and cannot simply be propagated to a calling D method. There is, however, an easy way to solve this problem: Just catch the exception in the C/C++ wrapper layer, pass the contents to D, and make the wrapper code rethrow the exception in the D world.</p>
|
||||
|
||||
<p>The implementation details of this are a bit crude, but the SWIG D module automatically takes care of this, as long as it is able to detect that an exception could potentially be thrown (e.g. because the C++ method has a <tt>throw(…)</tt> exception specification).</p>
|
||||
|
||||
<p>As this feature is implemented in exactly the same way it is for C#, please see the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for a more detailed explanation.</p>
|
||||
|
||||
|
||||
<H2><a name="D_directors"></a>20.7 D Directors</H2>
|
||||
|
||||
|
||||
<p>When the directors feature is activated, SWIG generates extra code on both the C++ and the D side to enable cross-language polymorphism. Essentially, this means that if you subclass a proxy class in D, C++ code can access any overridden virtual methods just as if you created a derived class in C++.</p>
|
||||
|
||||
<p>There is no D specific documentation yet, but the way the feature is implemented is very similar to how it is done in <a href="Java.html#Java_directors">Java</a> and <a href="CSharp.html#CSharp_directors">C#</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<H2><a name="D_other_features"></a>20.8 Other features</H2>
|
||||
|
||||
|
||||
<p>The <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature of SWIG is not yet supported for D – all class modules are written to the same package, regardless of which C++ namespace they are in.</p>
|
||||
|
||||
<p>Support of pointers to primitive types.</p>
|
||||
|
||||
|
||||
<H2><a name="D_typemap_examples"></a>20.9 D Typemap examples</H2>
|
||||
|
||||
|
||||
<p>There are no D-specific typemap examples yet. However, with the above <a href="D.html#D_typemap_name_comparison">name comparison table</a>, you should be able to get an idea what can be done by looking at the <a href="CSharp.html#CSharp_typemap_examples">corresponding C# section</a>.</p>
|
||||
|
||||
|
||||
|
||||
<H2><a name="D_planned_features"></a>20.10 Work in progress and planned features</H2>
|
||||
|
||||
|
||||
<p>There are a couple of features which are not implemented yet, but would be very useful and might be added in the near future:</p>
|
||||
|
||||
<ul>
|
||||
<li><em>Static linking:</em> Currently, the C wrapper code is compiled into a dynamic library, out of which the symbol addresses are looked up at runtime by the D part. If statically linking the different languages into one binary was supported, a tool-chain capable of performing IPO at link time could inline the wrapping code, effectively reducing the overhead for simple calls to zero.</li>
|
||||
<li><em>C array handling:</em> Many data structures in some C/C++ libraries contain array containing of a pointer to the first element and the element count. Currently, one must manually writing wrapper code to be able to access these from D. It should be possible to add a set of SWIG macros to semi-automatically generate conversion code.</li>
|
||||
<li><em>Operator overloading:</em> Currently, operator overloading is supported only to a very limited extent – many C++ operators are just ignored with a warning. The problem here is that the way D handles operator overloading differs quite a lot from the way C++ does it, both syntactically and semantically, and even more so since the advent of template-based operator overloading in D2.</li>
|
||||
</ul>
|
||||
|
||||
<p>Some generated code might also be a bit rough around the edges, particularly in the following areas:</p>
|
||||
|
||||
<ul>
|
||||
<li><em>Memory management:</em> Although the currently generated wrapper code works fine with regard to the GC for the test-suite, there might be issues coming up in real-world multi-threaded usage.</li>
|
||||
<li><em>D2 support</em>: Originally, the module has been developed for the use with D1, D2/Phobos support has been added in later. The basic features should work equally well for both, but there <em>could</em> be issues concerning const-correctness etc.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -52,6 +52,7 @@ Last update : SWIG-2.0.2 (in progress)
|
|||
<li><a href="R.html#R">R support</a></li>
|
||||
<li><a href="Ruby.html#Ruby">Ruby support</a></li>
|
||||
<li><a href="Tcl.html#Tcl">Tcl support</a></li>
|
||||
<li><a href="D.html#D">D support</a></li>
|
||||
</ul>
|
||||
|
||||
<H3>Developer Documentation</H3>
|
||||
|
|
|
@ -17,6 +17,7 @@ CCache.html
|
|||
Allegrocl.html
|
||||
CSharp.html
|
||||
Chicken.html
|
||||
D.html
|
||||
Go.html
|
||||
Guile.html
|
||||
Java.html
|
||||
|
|
|
@ -69,7 +69,7 @@ IOBJS = $(IWRAP:.i=.@OBJEXT@)
|
|||
CPP_DLLIBS = #-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \
|
||||
-L/usr/local/lib -lg++ -lstdc++ -lgcc
|
||||
|
||||
# Solaris workshop 5.0
|
||||
# Solaris workshop 5.0
|
||||
# CPP_DLLIBS = -L/opt/SUNWspro/lib -lCrun
|
||||
|
||||
# Symbols used for using shared libraries
|
||||
|
@ -159,7 +159,7 @@ tcl_cpp: $(SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
tcl_clean:
|
||||
rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
|
||||
rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@
|
||||
|
||||
|
@ -296,9 +296,9 @@ python_static_cpp: $(SRCS)
|
|||
$(CXX) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \
|
||||
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# -----------------------------------------------------------------
|
||||
# Running a Python example
|
||||
# -----------------------------------------------------------------
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
ifeq (,$(PY3))
|
||||
PYSCRIPT = runme.py
|
||||
|
@ -313,7 +313,7 @@ python_run: $(PYSCRIPT)
|
|||
|
||||
runme3.py: runme.py
|
||||
cp $< $@
|
||||
$(PY2TO3) -w $@ >/dev/null 2>&1
|
||||
$(PY2TO3) -w $@ >/dev/null 2>&1
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Cleaning the python examples
|
||||
|
@ -332,7 +332,7 @@ python_clean:
|
|||
|
||||
# Make sure these locate your Octave installation
|
||||
OCTAVE_INCLUDE= $(DEFS) @OCTAVEEXT@
|
||||
OCTAVE_LIB =
|
||||
OCTAVE_LIB =
|
||||
|
||||
# Extra Octave specific dynamic linking options
|
||||
OCTAVE_DLNK = @OCTAVEDYNAMICLINKING@
|
||||
|
@ -548,14 +548,14 @@ mzscheme: $(SRCS)
|
|||
mzscheme_cpp: $(SRCS)
|
||||
$(SWIG) -mzscheme -c++ $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(COMPILETOOL) $(MZC) `echo $(INCLUDES) | sed 's/-I/++ccf -I/g'` --cc $(ICXXSRCS) $(SRCS) $(CXXSRCS)
|
||||
$(CXXSHARED) $(CFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS)
|
||||
$(CXXSHARED) $(CFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Cleaning the mzscheme examples
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
mzscheme_clean:
|
||||
rm -f *_wrap* *~ .~*
|
||||
rm -f *_wrap* *~ .~*
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@
|
||||
|
||||
|
@ -643,7 +643,7 @@ ocaml_static_cpp: $(SRCS)
|
|||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(PROGFILE:%.ml=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
||||
-cclib "$(LIBS)" -cc '$(CXX)'
|
||||
-cclib "$(LIBS)" -cc '$(CXX)'
|
||||
|
||||
ocaml_static_cpp_toplevel: $(SRCS)
|
||||
$(OCAMLCORE)
|
||||
|
@ -661,7 +661,7 @@ ocaml_static_cpp_toplevel: $(SRCS)
|
|||
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
|
||||
$(INTERFACE:%.i=%.cmo) \
|
||||
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
|
||||
-cclib "$(LIBS)" -cc '$(CXX)'
|
||||
-cclib "$(LIBS)" -cc '$(CXX)'
|
||||
|
||||
ocaml_dynamic_cpp: $(SRCS)
|
||||
$(OCAMLCORE)
|
||||
|
@ -844,7 +844,7 @@ pike_cpp_static: $(SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
pike_clean:
|
||||
rm -f *_wrap* *~ .~* mypike@EXEEXT@
|
||||
rm -f *_wrap* *~ .~* mypike@EXEEXT@
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@
|
||||
|
||||
|
@ -861,7 +861,7 @@ CHICKEN_CFLAGS = @CHICKENOPTS@
|
|||
CHICKENOPTS = -quiet
|
||||
CHICKEN_MAIN =
|
||||
|
||||
# SWIG produces $(ISRCS) (the C wrapper file)
|
||||
# SWIG produces $(ISRCS) (the C wrapper file)
|
||||
# and $(CHICKEN_GENERATED_SCHEME) (the Scheme wrapper file):
|
||||
CHICKEN_GENERATED_SCHEME = $(INTERFACE:.i=.scm)
|
||||
CHICKEN_COMPILED_SCHEME = $(INTERFACE:.i=_chicken.c)
|
||||
|
@ -1053,12 +1053,12 @@ lua_clean:
|
|||
|
||||
allegrocl: $(SRCS)
|
||||
$(SWIG) -allegrocl -cwrap $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
allegrocl_cpp: $(SRCS)
|
||||
$(SWIG) -c++ -allegrocl $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
allegrocl_clean:
|
||||
|
@ -1087,12 +1087,12 @@ clisp_clean:
|
|||
|
||||
cffi: $(SRCS)
|
||||
$(SWIG) -cffi $(SWIGOPT) $(INTERFACEPATH)
|
||||
# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
# $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
cffi_cpp: $(SRCS)
|
||||
$(SWIG) -c++ -cffi $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
cffi_clean:
|
||||
|
@ -1106,12 +1106,12 @@ cffi_clean:
|
|||
|
||||
uffi: $(SRCS)
|
||||
$(SWIG) -uffi $(SWIGOPT) $(INTERFACEPATH)
|
||||
# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
|
||||
# $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
uffi_cpp: $(SRCS)
|
||||
$(SWIG) -c++ -uffi $(SWIGOPT) $(INTERFACEPATH)
|
||||
# $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
# $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
|
||||
# $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
uffi_clean:
|
||||
|
@ -1212,3 +1212,56 @@ go_clean:
|
|||
rm -f *_wrap* *_gc* .~* runme
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *.[568] *.a *@SO@
|
||||
|
||||
##################################################################
|
||||
##### D ######
|
||||
##################################################################
|
||||
|
||||
DLIBPREFIX = @DLIBPREFIX@
|
||||
|
||||
ifeq (2,$(D_VERSION))
|
||||
SWIGD = $(SWIG) -d -d2
|
||||
DCOMPILER = @D2COMPILER@
|
||||
else
|
||||
SWIGD = $(SWIG) -d
|
||||
DCOMPILER = @D1COMPILER@
|
||||
endif
|
||||
|
||||
ifeq (dmd,$(DCOMPILER))
|
||||
# DMD is 32bit only by now
|
||||
CFLAGS += -m32
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Build a dynamically loadable D wrapper for a C module
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
d: $(SRCS)
|
||||
$(SWIGD) $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CFLAGS) $(EXTRA_CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES)
|
||||
$(LDSHARED) $(CFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Build a dynamically loadable D wrapper for a C++ module
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
d_cpp: $(SRCS)
|
||||
$(SWIGD) -c++ $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CFLAGS) $(EXTRA_CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES)
|
||||
$(CXXSHARED) $(CFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Compile D files
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
d_compile: $(SRCS)
|
||||
$(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Clean the D examples
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
d_clean:
|
||||
rm -f *_wrap* *~ .~* runme runme.exe `find . -name \*.d | grep -v runme.d`
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,36 @@
|
|||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import example;
|
||||
|
||||
public class DCallback : Callback {
|
||||
public override void run() {
|
||||
Stdout( "DCallback.run()" ).newline;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto caller = new Caller();
|
||||
|
||||
Stdout( "Adding and calling a normal C++ callback" ).newline;
|
||||
Stdout( "----------------------------------------" ).newline;
|
||||
{
|
||||
scope auto callback = new Callback();
|
||||
caller.setCallback(callback);
|
||||
caller.call();
|
||||
caller.resetCallback();
|
||||
}
|
||||
|
||||
Stdout.newline;
|
||||
Stdout( "Adding and calling a D callback" ).newline;
|
||||
Stdout( "-------------------------------" ).newline;
|
||||
{
|
||||
scope auto callback = new DCallback();
|
||||
caller.setCallback(callback);
|
||||
caller.call();
|
||||
caller.resetCallback();
|
||||
}
|
||||
|
||||
Stdout.newline;
|
||||
Stdout( "D exit" ).newline;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
import example;
|
||||
|
||||
public class DCallback : Callback {
|
||||
public override void run() {
|
||||
writeln( "DCallback.run()" );
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto caller = new Caller();
|
||||
|
||||
writeln( "Adding and calling a normal C++ callback" );
|
||||
writeln( "----------------------------------------" );
|
||||
{
|
||||
scope auto callback = new Callback();
|
||||
caller.setCallback(callback);
|
||||
caller.call();
|
||||
caller.resetCallback();
|
||||
}
|
||||
|
||||
writeln();
|
||||
writeln( "Adding and calling a D callback" );
|
||||
writeln( "-------------------------------" );
|
||||
{
|
||||
scope auto callback = new DCallback();
|
||||
caller.setCallback(callback);
|
||||
caller.call();
|
||||
caller.resetCallback();
|
||||
}
|
||||
|
||||
writeln();
|
||||
writeln( "D exit" );
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
|
||||
virtual void run() { std::cout << "Callback::run()" << std::endl; }
|
||||
};
|
||||
|
||||
|
||||
class Caller {
|
||||
private:
|
||||
Callback *_callback;
|
||||
public:
|
||||
Caller(): _callback(0) {}
|
||||
~Caller() { delCallback(); }
|
||||
void delCallback() { delete _callback; _callback = 0; }
|
||||
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
|
||||
void resetCallback() { _callback = 0; }
|
||||
void call() { if (_callback) _callback->run(); }
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
/* turn on director wrapping Callback */
|
||||
%feature("director") Callback;
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# See top-level Makefile.in.
|
||||
callback
|
||||
class
|
||||
constants
|
||||
enum
|
||||
extend
|
||||
funcptr
|
||||
simple
|
||||
variables
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,58 @@
|
|||
// This example illustrates how C++ classes can be used from D using SWIG.
|
||||
// The D class gets mapped onto the C++ class and behaves as if it is a D class.
|
||||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import example;
|
||||
|
||||
void main() {
|
||||
// ----- Object creation -----
|
||||
|
||||
Stdout( "Creating some objects:" ).newline;
|
||||
|
||||
{
|
||||
scope Square s = new Square(10);
|
||||
scope Circle c = new Circle(10);
|
||||
|
||||
// ----- Access a static member -----
|
||||
Stdout.format( "{} shapes were created.", Shape.nshapes ).newline;
|
||||
|
||||
// ----- Member data access -----
|
||||
|
||||
// Notice how we can do this using functions specific to
|
||||
// the 'Circle' class.
|
||||
c.x = 20;
|
||||
c.y = 30;
|
||||
|
||||
// Now use the same functions in the base class
|
||||
Shape shape = s;
|
||||
shape.x = -10;
|
||||
shape.y = 5;
|
||||
|
||||
Stdout( "\nHere is their current position:" ).newline;
|
||||
Stdout.format( " Circle = ( {}, {} )", c.x, c.y ).newline;
|
||||
Stdout.format( " Square = ( {}, {} )", s.x, s.y ).newline;
|
||||
|
||||
// ----- Call some methods -----
|
||||
|
||||
Stdout( "\nHere are some properties of the shapes:" ).newline;
|
||||
Shape[] shapes = [ cast(Shape) c, cast(Shape) s ];
|
||||
foreach ( currentShape; shapes )
|
||||
{
|
||||
Stdout.format( " {}", currentShape.classinfo.name ).newline;
|
||||
Stdout.format( " area = {}", currentShape.area() ).newline;
|
||||
Stdout.format( " perimeter = {}", currentShape.perimeter() ).newline;
|
||||
}
|
||||
|
||||
// Notice how the area() and perimeter() functions really
|
||||
// invoke the appropriate virtual method on each object.
|
||||
|
||||
// ----- Delete everything -----
|
||||
Stdout( "\nGuess I'll clean up now:" ).newline;
|
||||
// Note: when this using scope is exited the D destructors are called which
|
||||
// in turn call the C++ destructors.
|
||||
}
|
||||
|
||||
Stdout.format( "{} shapes remain", Shape.nshapes ).newline;
|
||||
Stdout( "\nGoodbye!" ).newline;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// This example illustrates how C++ classes can be used from D using SWIG.
|
||||
// The D class gets mapped onto the C++ class and behaves as if it is a D class.
|
||||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
import example;
|
||||
|
||||
void main() {
|
||||
// ----- Object creation -----
|
||||
|
||||
writeln( "Creating some objects:" );
|
||||
|
||||
{
|
||||
scope Square s = new Square(10);
|
||||
scope Circle c = new Circle(10);
|
||||
|
||||
// ----- Access a static member -----
|
||||
writefln( "%s shapes were created.", Shape.nshapes );
|
||||
|
||||
// ----- Member data access -----
|
||||
|
||||
// Notice how we can do this using functions specific to
|
||||
// the 'Circle' class.
|
||||
c.x = 20;
|
||||
c.y = 30;
|
||||
|
||||
// Now use the same functions in the base class
|
||||
Shape shape = s;
|
||||
shape.x = -10;
|
||||
shape.y = 5;
|
||||
|
||||
writeln( "\nHere is their current position:" );
|
||||
writefln( " Circle = ( %s, %s )", c.x, c.y );
|
||||
writefln( " Square = ( %s, %s )", s.x, s.y );
|
||||
|
||||
// ----- Call some methods -----
|
||||
|
||||
writeln( "\nHere are some properties of the shapes:" );
|
||||
Shape[] shapes = [ cast(Shape) c, cast(Shape) s ];
|
||||
foreach ( currentShape; shapes )
|
||||
{
|
||||
writefln( " %s", currentShape.classinfo.name );
|
||||
writefln( " area = %s", currentShape.area() );
|
||||
writefln( " perimeter = %s", currentShape.perimeter() );
|
||||
}
|
||||
|
||||
// Notice how the area() and perimeter() functions really
|
||||
// invoke the appropriate virtual method on each object.
|
||||
|
||||
// ----- Delete everything -----
|
||||
writeln( "\nGuess I'll clean up now:" );
|
||||
// Note: when this using scope is exited the D destructors are called which
|
||||
// in turn call the C++ destructors.
|
||||
}
|
||||
|
||||
writefln( "%s shapes remain", Shape.nshapes );
|
||||
writeln( "\nGoodbye!" );
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/* File : example.c */
|
||||
|
||||
#include "example.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
/* Move the shape to a new location */
|
||||
void Shape::move(double dx, double dy) {
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
int Shape::nshapes = 0;
|
||||
|
||||
double Circle::area(void) {
|
||||
return M_PI*radius*radius;
|
||||
}
|
||||
|
||||
double Circle::perimeter(void) {
|
||||
return 2*M_PI*radius;
|
||||
}
|
||||
|
||||
double Square::area(void) {
|
||||
return width*width;
|
||||
}
|
||||
|
||||
double Square::perimeter(void) {
|
||||
return 4*width;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* File : example.h */
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
nshapes++;
|
||||
}
|
||||
virtual ~Shape() {
|
||||
nshapes--;
|
||||
};
|
||||
double x, y;
|
||||
void move(double dx, double dy);
|
||||
virtual double area(void) = 0;
|
||||
virtual double perimeter(void) = 0;
|
||||
static int nshapes;
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
private:
|
||||
double radius;
|
||||
public:
|
||||
Circle(double r) : radius(r) { };
|
||||
virtual double area(void);
|
||||
virtual double perimeter(void);
|
||||
};
|
||||
|
||||
class Square : public Shape {
|
||||
private:
|
||||
double width;
|
||||
public:
|
||||
Square(double w) : width(w) { };
|
||||
virtual double area(void);
|
||||
virtual double perimeter(void);
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ example_wrap.c
|
||||
EXTRA_LDFLAGS = example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,28 @@
|
|||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
Stdout.formatln("ICONST = {} (should be 42)", example.ICONST);
|
||||
Stdout.formatln("FCONST = {} (should be 2.18)", example.FCONST);
|
||||
Stdout.formatln("CCONST = {} (should be 'x')", example.CCONST);
|
||||
Stdout.formatln("CCONST2 = {} (this should be on a new line)", example.CCONST2);
|
||||
Stdout.formatln("SCONST = {} (should be 'Hello World')", example.SCONST);
|
||||
Stdout.formatln("SCONST2 = {} (should be '\"Hello World\"')", example.SCONST2);
|
||||
Stdout.formatln("EXPR = {} (should be 48.55)", example.EXPR);
|
||||
Stdout.formatln("iconst = {} (should be 37)", example.iconst);
|
||||
Stdout.formatln("fconst = {} (should be 3.14)", example.fconst);
|
||||
|
||||
static if (is(typeof(example.EXTERN))) {
|
||||
Stdout.formatln("EXTERN should not be defined, but is: {}.", example.EXTERN );
|
||||
} else {
|
||||
Stdout.formatln("EXTERN isn't defined (good)");
|
||||
}
|
||||
|
||||
static if (is(typeof(example.FOO))) {
|
||||
Stdout.formatln("FOO should not be defined, but is: {}.", example.FOO);
|
||||
} else {
|
||||
Stdout.formatln("FOO isn't defined (good)");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
writefln("ICONST = %s (should be 42)", example.ICONST);
|
||||
writefln("FCONST = %s (should be 2.1828)", example.FCONST);
|
||||
writefln("CCONST = %s (should be 'x')", example.CCONST);
|
||||
writefln("CCONST2 = %s (this should be on a new line)", example.CCONST2);
|
||||
writefln("SCONST = %s (should be 'Hello World')", example.SCONST);
|
||||
writefln("SCONST2 = %s (should be '\"Hello World\"')", example.SCONST2);
|
||||
writefln("EXPR = %s (should be 48.5484)", example.EXPR);
|
||||
writefln("iconst = %s (should be 37)", example.iconst);
|
||||
writefln("fconst = %s (should be 3.14)", example.fconst);
|
||||
|
||||
static if (is(typeof(example.EXTERN))) {
|
||||
writefln("EXTERN should not be defined, but is: %s.", example.EXTERN );
|
||||
} else {
|
||||
writeln("EXTERN isn't defined (good)");
|
||||
}
|
||||
|
||||
static if (is(typeof(example.FOO))) {
|
||||
writefln("FOO should not be defined, but is: %s.", example.FOO);
|
||||
} else {
|
||||
writeln("FOO isn't defined (good)");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* This file was automatically generated by SWIG (http://www.swig.org).
|
||||
* Version 1.3.41
|
||||
*
|
||||
* Do not make changes to this file unless you know what you are doing--modify
|
||||
* the SWIG interface file instead.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
module example;
|
||||
|
||||
static import example_wrap;
|
||||
|
||||
static import tango.stdc.stringz;
|
||||
|
||||
public const int ICONST = 42;
|
||||
public const double FCONST = 2.1828;
|
||||
public const char CCONST = 'x';
|
||||
public const char CCONST2 = '\n';
|
||||
public const char[] SCONST = "Hello World";
|
||||
public const char[] SCONST2 = "\"Hello World\"";
|
||||
public const double EXPR = 42+3*(2.1828);
|
||||
public const int iconst = 37;
|
||||
public const double fconst = 3.14;
|
|
@ -0,0 +1,32 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
/* Force the generated D code to use the C constant values rather than
|
||||
retrieving them at runtime. You can also try disabling the feature and
|
||||
compare the generated code. */
|
||||
%dnativeconst;
|
||||
|
||||
|
||||
/* A few preprocessor macros */
|
||||
|
||||
#define ICONST 42
|
||||
#define FCONST 2.1828
|
||||
#define CCONST 'x'
|
||||
#define CCONST2 '\n'
|
||||
#define SCONST "Hello World"
|
||||
#define SCONST2 "\"Hello World\""
|
||||
|
||||
/* This should work just fine */
|
||||
#define EXPR ICONST + 3*(FCONST)
|
||||
|
||||
/* This shouldn't do anything */
|
||||
#define EXTERN extern
|
||||
|
||||
/* Neither should this (BAR isn't defined) */
|
||||
#define FOO (ICONST + BAR)
|
||||
|
||||
|
||||
/* The following directives also produce constants */
|
||||
|
||||
%constant int iconst = 37;
|
||||
%constant double fconst = 3.14;
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,28 @@
|
|||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import example;
|
||||
|
||||
void main() {
|
||||
Stdout( "Printing out some enum values:" ).newline;
|
||||
Stdout(" color:").newline;
|
||||
Stdout.formatln(" {} = {}", color.RED, cast(int)color.RED);
|
||||
Stdout.formatln(" {} = {}", color.BLUE, cast(int)color.BLUE);
|
||||
Stdout.formatln(" {} = {}", color.GREEN, cast(int)color.GREEN);
|
||||
|
||||
Stdout("\n Foo.speed:").newline;
|
||||
Stdout.formatln(" Foo.{} = {}", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE);
|
||||
Stdout.formatln(" Foo.{} = {}", Foo.speed.WARP, cast(int)Foo.speed.WARP);
|
||||
Stdout.formatln(" Foo.{} = {}", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS);
|
||||
|
||||
Stdout("\nTesting use of enums with functions:").newline;
|
||||
example.enum_test(color.RED, Foo.speed.IMPULSE);
|
||||
example.enum_test(color.BLUE, Foo.speed.WARP);
|
||||
example.enum_test(color.GREEN, Foo.speed.LUDICROUS);
|
||||
|
||||
Stdout( "\nTesting use of enum with class method:" ).newline;
|
||||
scope f = new Foo();
|
||||
f.enum_test(Foo.speed.IMPULSE);
|
||||
f.enum_test(Foo.speed.WARP);
|
||||
f.enum_test(Foo.speed.LUDICROUS);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
import example;
|
||||
|
||||
void main() {
|
||||
writeln( "Printing out some enum values:" );
|
||||
writeln(" color:");
|
||||
writefln(" %s = %s", color.RED, cast(int)color.RED);
|
||||
writefln(" %s = %s", color.BLUE, cast(int)color.BLUE);
|
||||
writefln(" %s = %s", color.GREEN, cast(int)color.GREEN);
|
||||
|
||||
writeln("\n Foo.speed:");
|
||||
writefln(" Foo.%s = %s", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE);
|
||||
writefln(" Foo.%s = %s", Foo.speed.WARP, cast(int)Foo.speed.WARP);
|
||||
writefln(" Foo.%s = %s", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS);
|
||||
|
||||
writeln("\nTesting use of enums with functions:");
|
||||
example.enum_test(color.RED, Foo.speed.IMPULSE);
|
||||
example.enum_test(color.BLUE, Foo.speed.WARP);
|
||||
example.enum_test(color.GREEN, Foo.speed.LUDICROUS);
|
||||
|
||||
writeln( "\nTesting use of enum with class method:" );
|
||||
scope f = new Foo();
|
||||
f.enum_test(Foo.speed.IMPULSE);
|
||||
f.enum_test(Foo.speed.WARP);
|
||||
f.enum_test(Foo.speed.LUDICROUS);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void Foo::enum_test(speed s) {
|
||||
if (s == IMPULSE) {
|
||||
printf("IMPULSE speed\n");
|
||||
} else if (s == WARP) {
|
||||
printf("WARP speed\n");
|
||||
} else if (s == LUDICROUS) {
|
||||
printf("LUDICROUS speed\n");
|
||||
} else {
|
||||
printf("Unknown speed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void enum_test(color c, Foo::speed s) {
|
||||
if (c == RED) {
|
||||
printf("color = RED, ");
|
||||
} else if (c == BLUE) {
|
||||
printf("color = BLUE, ");
|
||||
} else if (c == GREEN) {
|
||||
printf("color = GREEN, ");
|
||||
} else {
|
||||
printf("color = Unknown color!, ");
|
||||
}
|
||||
if (s == Foo::IMPULSE) {
|
||||
printf("speed = IMPULSE speed\n");
|
||||
} else if (s == Foo::WARP) {
|
||||
printf("speed = WARP speed\n");
|
||||
} else if (s == Foo::LUDICROUS) {
|
||||
printf("speed = LUDICROUS speed\n");
|
||||
} else {
|
||||
printf("speed = Unknown speed!\n");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* File : example.h */
|
||||
|
||||
enum color { RED, BLUE, GREEN };
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() { }
|
||||
enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 };
|
||||
void enum_test(speed s);
|
||||
};
|
||||
|
||||
void enum_test(color c, Foo::speed s);
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,75 @@
|
|||
/// This file illustrates the cross language polymorphism using directors.
|
||||
module runme;
|
||||
|
||||
import example;
|
||||
import tango.io.Stdout;
|
||||
|
||||
// CEO class, which overrides Employee.getPosition().
|
||||
class CEO : Manager {
|
||||
public:
|
||||
this( char[] name ) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
override char[] getPosition() {
|
||||
return "CEO";
|
||||
}
|
||||
|
||||
// Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory.
|
||||
void disownMemory() {
|
||||
swigCMemOwn = false;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Create an instance of CEO, a class derived from the D proxy of the
|
||||
// underlying C++ class. The calls to getName() and getPosition() are standard,
|
||||
// the call to getTitle() uses the director wrappers to call CEO.getPosition().
|
||||
|
||||
auto e = new CEO( "Alice" );
|
||||
Stdout.formatln( "{} is a {}.", e.getName(), e.getPosition() );
|
||||
Stdout.formatln( "Just call her '{}'.", e.getTitle() );
|
||||
Stdout( "----------------------" ).newline;
|
||||
|
||||
{
|
||||
// Create a new EmployeeList instance. This class does not have a C++
|
||||
// director wrapper, but can be used freely with other classes that do.
|
||||
scope auto list = new EmployeeList();
|
||||
|
||||
// EmployeeList owns its items, so we must surrender ownership of objects we add.
|
||||
e.disownMemory();
|
||||
list.addEmployee(e);
|
||||
Stdout( "----------------------" ).newline;
|
||||
|
||||
// Now we access the first four items in list (three are C++ objects that
|
||||
// EmployeeList's constructor adds, the last is our CEO). The virtual
|
||||
// methods of all these instances are treated the same. For items 0, 1, and
|
||||
// 2, all methods resolve in C++. For item 3, our CEO, getTitle calls
|
||||
// getPosition which resolves in D. The call to getPosition is
|
||||
// slightly different, however, because of the overidden getPosition() call, since
|
||||
// now the object reference has been "laundered" by passing through
|
||||
// EmployeeList as an Employee*. Previously, D resolved the call
|
||||
// immediately in CEO, but now D thinks the object is an instance of
|
||||
// class Employee. So the call passes through the
|
||||
// Employee proxy class and on to the C wrappers and C++ director,
|
||||
// eventually ending up back at the D CEO implementation of getPosition().
|
||||
// The call to getTitle() for item 3 runs the C++ Employee::getTitle()
|
||||
// method, which in turn calls getPosition(). This virtual method call
|
||||
// passes down through the C++ director class to the D implementation
|
||||
// in CEO. All this routing takes place transparently.
|
||||
|
||||
Stdout( "(position, title) for items 0-3:" ).newline;
|
||||
Stdout.formatln( " {}, '{}'", list.getItem(0).getPosition(), list.getItem(0).getTitle() );
|
||||
Stdout.formatln( " {}, '{}'", list.getItem(1).getPosition(), list.getItem(1).getTitle() );
|
||||
Stdout.formatln( " {}, '{}'", list.getItem(2).getPosition(), list.getItem(2).getTitle() );
|
||||
Stdout.formatln( " {}, '{}'", list.getItem(3).getPosition(), list.getItem(3).getTitle() );
|
||||
Stdout( "----------------------" ).newline;
|
||||
|
||||
// All Employees will be destroyed when the EmployeeList goes out of scope,
|
||||
// including the CEO instance.
|
||||
}
|
||||
Stdout( "----------------------" ).newline;
|
||||
|
||||
// All done.
|
||||
Stdout( "Exiting cleanly from D code." ).newline;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/// This file illustrates the cross language polymorphism using directors.
|
||||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
import example;
|
||||
|
||||
// CEO class, which overrides Employee.getPosition().
|
||||
class CEO : Manager {
|
||||
public:
|
||||
this( string name ) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
override string getPosition() const {
|
||||
return "CEO";
|
||||
}
|
||||
|
||||
// Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory.
|
||||
void disownMemory() {
|
||||
swigCMemOwn = false;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Create an instance of CEO, a class derived from the D proxy of the
|
||||
// underlying C++ class. The calls to getName() and getPosition() are standard,
|
||||
// the call to getTitle() uses the director wrappers to call CEO.getPosition().
|
||||
|
||||
auto e = new CEO( "Alice" );
|
||||
writefln( "%s is a %s.", e.getName(), e.getPosition() );
|
||||
writefln( "Just call her '%s'.", e.getTitle() );
|
||||
writeln( "----------------------" );
|
||||
|
||||
{
|
||||
// Create a new EmployeeList instance. This class does not have a C++
|
||||
// director wrapper, but can be used freely with other classes that do.
|
||||
scope auto list = new EmployeeList();
|
||||
|
||||
// EmployeeList owns its items, so we must surrender ownership of objects we add.
|
||||
e.disownMemory();
|
||||
list.addEmployee(e);
|
||||
writeln( "----------------------" );
|
||||
|
||||
// Now we access the first four items in list (three are C++ objects that
|
||||
// EmployeeList's constructor adds, the last is our CEO). The virtual
|
||||
// methods of all these instances are treated the same. For items 0, 1, and
|
||||
// 2, all methods resolve in C++. For item 3, our CEO, getTitle calls
|
||||
// getPosition which resolves in D. The call to getPosition is
|
||||
// slightly different, however, because of the overidden getPosition() call, since
|
||||
// now the object reference has been "laundered" by passing through
|
||||
// EmployeeList as an Employee*. Previously, D resolved the call
|
||||
// immediately in CEO, but now D thinks the object is an instance of
|
||||
// class Employee. So the call passes through the
|
||||
// Employee proxy class and on to the C wrappers and C++ director,
|
||||
// eventually ending up back at the D CEO implementation of getPosition().
|
||||
// The call to getTitle() for item 3 runs the C++ Employee::getTitle()
|
||||
// method, which in turn calls getPosition(). This virtual method call
|
||||
// passes down through the C++ director class to the D implementation
|
||||
// in CEO. All this routing takes place transparently.
|
||||
|
||||
writeln( "(position, title) for items 0-3:" );
|
||||
writefln( " %s, '%s'", list.getItem(0).getPosition(), list.getItem(0).getTitle() );
|
||||
writefln( " %s, '%s'", list.getItem(1).getPosition(), list.getItem(1).getTitle() );
|
||||
writefln( " %s, '%s'", list.getItem(2).getPosition(), list.getItem(2).getTitle() );
|
||||
writefln( " %s, '%s'", list.getItem(3).getPosition(), list.getItem(3).getTitle() );
|
||||
writeln( "----------------------" );
|
||||
|
||||
// All Employees will be destroyed when the EmployeeList goes out of scope,
|
||||
// including the CEO instance.
|
||||
}
|
||||
writeln( "----------------------" );
|
||||
|
||||
// All done.
|
||||
writeln( "Exiting cleanly from D code." );
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
class Employee {
|
||||
private:
|
||||
std::string name;
|
||||
public:
|
||||
Employee(const char* n): name(n) {}
|
||||
virtual std::string getTitle() { return getPosition() + " " + getName(); }
|
||||
virtual std::string getName() { return name; }
|
||||
virtual std::string getPosition() const { return "Employee"; }
|
||||
virtual ~Employee() { printf("~Employee() @ %p\n", this); }
|
||||
};
|
||||
|
||||
|
||||
class Manager: public Employee {
|
||||
public:
|
||||
Manager(const char* n): Employee(n) {}
|
||||
virtual std::string getPosition() const { return "Manager"; }
|
||||
};
|
||||
|
||||
|
||||
class EmployeeList {
|
||||
std::vector<Employee*> list;
|
||||
public:
|
||||
EmployeeList() {
|
||||
list.push_back(new Employee("Bob"));
|
||||
list.push_back(new Employee("Jane"));
|
||||
list.push_back(new Manager("Ted"));
|
||||
}
|
||||
void addEmployee(Employee *p) {
|
||||
list.push_back(p);
|
||||
std::cout << "New employee added. Current employees are:" << std::endl;
|
||||
std::vector<Employee*>::iterator i;
|
||||
for (i=list.begin(); i!=list.end(); i++) {
|
||||
std::cout << " " << (*i)->getTitle() << std::endl;
|
||||
}
|
||||
}
|
||||
const Employee *getItem(int i) {
|
||||
return list[i];
|
||||
}
|
||||
~EmployeeList() {
|
||||
std::vector<Employee*>::iterator i;
|
||||
std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl;
|
||||
for (i=list.begin(); i!=list.end(); i++) {
|
||||
delete *i;
|
||||
}
|
||||
std::cout << "~EmployeeList empty." << std::endl;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
/* turn on director wrapping for Manager */
|
||||
%feature("director") Employee;
|
||||
%feature("director") Manager;
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.c example_wrap.c
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,34 @@
|
|||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
static import example;
|
||||
|
||||
extern(C) int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
extern(C) int sub(int a, int b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
extern(C) int mul(int a, int b) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
void main() {
|
||||
int a = 37;
|
||||
int b = 42;
|
||||
|
||||
Stdout( "a = " )( a ).newline;
|
||||
Stdout( "b = " )( b ).newline;
|
||||
|
||||
Stdout( "Trying some C callback functions:" ).newline;
|
||||
Stdout( " ADD(a,b) = " )( example.do_op( a, b, example.ADD ) ).newline;
|
||||
Stdout( " SUB(a,b) = " )( example.do_op( a, b, example.SUB ) ).newline;
|
||||
Stdout( " MUL(a,b) = " )( example.do_op( a, b, example.MUL ) ).newline;
|
||||
|
||||
Stdout( "Now the same with callback functions defined in D:" ).newline;
|
||||
Stdout( " add(a,b) = " )( example.do_op( a, b, &add ) ).newline;
|
||||
Stdout( " sub(a,b) = " )( example.do_op( a, b, &sub ) ).newline;
|
||||
Stdout( " mul(a,b) = " )( example.do_op( a, b, &mul ) ).newline;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
static import example;
|
||||
|
||||
extern(C) int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
extern(C) int sub(int a, int b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
extern(C) int mul(int a, int b) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
void main() {
|
||||
int a = 37;
|
||||
int b = 42;
|
||||
|
||||
writefln( "a = %s", a );
|
||||
writefln( "b = %s", b );
|
||||
|
||||
writeln( "Trying some C callback functions:" );
|
||||
writefln( " ADD(a,b) = %s", example.do_op( a, b, example.ADD ) );
|
||||
writefln( " SUB(a,b) = %s", example.do_op( a, b, example.SUB ) );
|
||||
writefln( " MUL(a,b) = %s", example.do_op( a, b, example.MUL ) );
|
||||
|
||||
writeln( "Now the same with callback functions defined in D:" );
|
||||
writefln( " add(a,b) = %s", example.do_op( a, b, &add ) );
|
||||
writefln( " sub(a,b) = %s", example.do_op( a, b, &sub ) );
|
||||
writefln( " mul(a,b) = %s", example.do_op( a, b, &mul ) );
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* File : example.c */
|
||||
|
||||
int do_op(int a, int b, int (*op)(int,int)) {
|
||||
return (*op)(a,b);
|
||||
}
|
||||
|
||||
int add(int a, int b) {
|
||||
return a+b;
|
||||
}
|
||||
|
||||
int sub(int a, int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
int mul(int a, int b) {
|
||||
return a*b;
|
||||
}
|
||||
|
||||
int (*funcvar)(int,int) = add;
|
|
@ -0,0 +1,9 @@
|
|||
/* file: example.h */
|
||||
|
||||
extern int do_op(int,int, int (*op)(int,int));
|
||||
extern int add(int,int);
|
||||
extern int sub(int,int);
|
||||
extern int mul(int,int);
|
||||
|
||||
extern int (*funcvar)(int,int);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Wrap a function taking a pointer to a function */
|
||||
extern int do_op(int a, int b, int (*op)(int, int));
|
||||
|
||||
/* Now install a bunch of "ops" as constants */
|
||||
%constant int (*ADD)(int,int) = add;
|
||||
%constant int (*SUB)(int,int) = sub;
|
||||
%constant int (*MUL)(int,int) = mul;
|
||||
|
||||
extern int (*funcvar)(int,int);
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.c example_wrap.c
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,27 @@
|
|||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
/*
|
||||
* Call our gcd() function.
|
||||
*/
|
||||
int x = 42;
|
||||
int y = 105;
|
||||
int g = example.gcd( x, y );
|
||||
Stdout.format( "The gcd of {} and {} is {}.", x, y, g ).newline;
|
||||
|
||||
/*
|
||||
* Manipulate the Foo global variable.
|
||||
*/
|
||||
|
||||
// Output its current value
|
||||
Stdout.format( "Foo = {}", example.Foo ).newline;
|
||||
|
||||
// Change its value
|
||||
example.Foo = 3.1415926;
|
||||
|
||||
// See if the change took effect
|
||||
Stdout.format( "Foo = {}", example.Foo ).newline;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
/*
|
||||
* Call our gcd() function.
|
||||
*/
|
||||
int x = 42;
|
||||
int y = 105;
|
||||
int g = example.gcd(x, y);
|
||||
writefln("The gcd of %s and %s is %s.", x, y, g);
|
||||
|
||||
/*
|
||||
* Manipulate the Foo global variable.
|
||||
*/
|
||||
|
||||
// Output its current value
|
||||
writefln("Foo = %s", example.Foo);
|
||||
|
||||
// Change its value
|
||||
example.Foo = 3.1415926;
|
||||
|
||||
// See if the change took effect
|
||||
writefln("Foo = %s", example.Foo);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* File : example.c */
|
||||
|
||||
/* A global variable */
|
||||
double Foo = 3.0;
|
||||
|
||||
/* Compute the greatest common divisor of positive integers */
|
||||
int gcd(int x, int y) {
|
||||
int g;
|
||||
g = y;
|
||||
while (x > 0) {
|
||||
g = x;
|
||||
x = y % x;
|
||||
y = g;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%inline %{
|
||||
extern int gcd(int x, int y);
|
||||
extern double Foo;
|
||||
%}
|
|
@ -0,0 +1,28 @@
|
|||
ifeq (2,$(D_VERSION))
|
||||
WORKING_DIR = d2/
|
||||
else
|
||||
WORKING_DIR = d1/
|
||||
endif
|
||||
|
||||
TOP = ../../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
EXTRA_CFLAGS = -I../ ../example.c example_wrap.c
|
||||
EXTRA_LDFLAGS = example.o example_wrap.o
|
||||
TARGET = example_wrap
|
||||
SWIGOPT =
|
||||
DSRCS = *.d
|
||||
DFLAGS = -ofrunme
|
||||
|
||||
|
||||
all:: d
|
||||
|
||||
d::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \
|
||||
$(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
|
||||
|
||||
clean::
|
||||
cd $(WORKING_DIR); \
|
||||
$(MAKE) -f $(TOP)/Makefile d_clean
|
||||
|
||||
check: all
|
|
@ -0,0 +1,71 @@
|
|||
// This example illustrates global variable access from C#.
|
||||
module runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
// Try to set the values of some global variables
|
||||
example.ivar = 42;
|
||||
example.svar = -31000;
|
||||
example.lvar = 65537;
|
||||
example.uivar = 123456;
|
||||
example.usvar = 61000;
|
||||
example.ulvar = 654321;
|
||||
example.scvar = -13;
|
||||
example.ucvar = 251;
|
||||
example.cvar = 'S';
|
||||
example.fvar = 3.14159f;
|
||||
example.dvar = 2.1828;
|
||||
example.strvar = "Hello World";
|
||||
example.iptrvar = example.new_int(37);
|
||||
example.ptptr = example.new_Point(37,42);
|
||||
example.name = "Bill";
|
||||
|
||||
// Now print out the values of the variables
|
||||
Stdout.formatln( "Variables (printed from D):" );
|
||||
Stdout.formatln( "ivar = {}", example.ivar );
|
||||
Stdout.formatln( "svar = {}", example.svar );
|
||||
Stdout.formatln( "lvar = {}", example.lvar );
|
||||
Stdout.formatln( "uivar = {}", example.uivar );
|
||||
Stdout.formatln( "usvar = {}", example.usvar );
|
||||
Stdout.formatln( "ulvar = {}", example.ulvar );
|
||||
Stdout.formatln( "scvar = {}", example.scvar );
|
||||
Stdout.formatln( "ucvar = {}", example.ucvar );
|
||||
Stdout.formatln( "fvar = {}", example.fvar );
|
||||
Stdout.formatln( "dvar = {}", example.dvar );
|
||||
Stdout.formatln( "cvar = {}", example.cvar );
|
||||
Stdout.formatln( "strvar = {}", example.strvar );
|
||||
Stdout.formatln( "cstrvar = {}", example.cstrvar );
|
||||
Stdout.formatln( "iptrvar = {}", example.iptrvar );
|
||||
Stdout.formatln( "name = {}", example.name );
|
||||
Stdout.formatln( "ptptr = {} {}", example.ptptr, example.Point_print(example.ptptr) );
|
||||
Stdout.formatln( "pt = {} {}", example.pt, example.Point_print(example.pt) );
|
||||
Stdout.formatln( "status = {}", example.status );
|
||||
|
||||
Stdout.formatln( "\nVariables (printed from the C library):" );
|
||||
example.print_vars();
|
||||
|
||||
Stdout.formatln( "\nNow I'm going to try and modify some read only variables:" );
|
||||
Stdout.formatln( "Checking that the read only variables are readonly..." );
|
||||
|
||||
Stdout( " 'path'..." );
|
||||
static if ( is( typeof( example.path = "a" ) ) )
|
||||
Stdout.formatln("Oh dear, this variable is not read only!");
|
||||
else
|
||||
Stdout.formatln("Good.");
|
||||
|
||||
Stdout( " 'status'..." );
|
||||
static if ( is( typeof( example.status = 2 ) ) )
|
||||
Stdout.formatln("Oh dear, this variable is not read only!");
|
||||
else
|
||||
Stdout.formatln("Good.");
|
||||
|
||||
Stdout.formatln( "\nI'm going to try and update a structure variable:" );
|
||||
|
||||
example.pt = example.ptptr;
|
||||
|
||||
Stdout( "The new value is " ).flush;
|
||||
example.pt_print();
|
||||
Stdout.formatln( "You should see the value {}", example.Point_print(example.ptptr) );
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// This example illustrates global variable access from C#.
|
||||
module runme;
|
||||
|
||||
import std.stdio;
|
||||
static import example;
|
||||
|
||||
void main() {
|
||||
// Try to set the values of some global variables
|
||||
example.ivar = 42;
|
||||
example.svar = -31000;
|
||||
example.lvar = 65537;
|
||||
example.uivar = 123456;
|
||||
example.usvar = 61000;
|
||||
example.ulvar = 654321;
|
||||
example.scvar = -13;
|
||||
example.ucvar = 251;
|
||||
example.cvar = 'S';
|
||||
example.fvar = 3.14159f;
|
||||
example.dvar = 2.1828;
|
||||
example.strvar = "Hello World";
|
||||
example.iptrvar = example.new_int(37);
|
||||
example.ptptr = example.new_Point(37,42);
|
||||
example.name = "Bill";
|
||||
|
||||
// Now print out the values of the variables
|
||||
writefln( "Variables (printed from D):" );
|
||||
writefln( "ivar = %s", example.ivar );
|
||||
writefln( "svar = %s", example.svar );
|
||||
writefln( "lvar = %s", example.lvar );
|
||||
writefln( "uivar = %s", example.uivar );
|
||||
writefln( "usvar = %s", example.usvar );
|
||||
writefln( "ulvar = %s", example.ulvar );
|
||||
writefln( "scvar = %s", example.scvar );
|
||||
writefln( "ucvar = %s", example.ucvar );
|
||||
writefln( "fvar = %s", example.fvar );
|
||||
writefln( "dvar = %s", example.dvar );
|
||||
writefln( "cvar = %s", example.cvar );
|
||||
writefln( "strvar = %s", example.strvar );
|
||||
writefln( "cstrvar = %s", example.cstrvar );
|
||||
writefln( "iptrvar = %s", example.iptrvar );
|
||||
writefln( "name = %s", example.name );
|
||||
writefln( "ptptr = %s %s", example.ptptr, example.Point_print(example.ptptr) );
|
||||
writefln( "pt = %s %s", example.pt, example.Point_print(example.pt) );
|
||||
writefln( "status = %s", example.status );
|
||||
|
||||
writefln( "\nVariables (printed from the C library):" );
|
||||
example.print_vars();
|
||||
|
||||
writefln( "\nNow I'm going to try and modify some read only variables:" );
|
||||
writefln( "Checking that the read only variables are readonly..." );
|
||||
|
||||
writeln( " 'path'..." );
|
||||
static if ( is( typeof( example.path = "a" ) ) )
|
||||
writefln("Oh dear, this variable is not read only!");
|
||||
else
|
||||
writefln("Good.");
|
||||
|
||||
writeln( " 'status'..." );
|
||||
static if ( is( typeof( example.status = 2 ) ) )
|
||||
writefln("Oh dear, this variable is not read only!");
|
||||
else
|
||||
writefln("Good.");
|
||||
|
||||
writefln( "\nI'm going to try and update a structure variable:" );
|
||||
|
||||
example.pt = example.ptptr;
|
||||
|
||||
write( "The new value is " );
|
||||
example.pt_print();
|
||||
writefln( "You should see the value %s", example.Point_print(example.ptptr) );
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/* File : example.c */
|
||||
|
||||
/* I'm a file containing some C global variables */
|
||||
|
||||
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
|
||||
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
|
||||
# define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "example.h"
|
||||
|
||||
int ivar = 0;
|
||||
short svar = 0;
|
||||
long lvar = 0;
|
||||
unsigned int uivar = 0;
|
||||
unsigned short usvar = 0;
|
||||
unsigned long ulvar = 0;
|
||||
signed char scvar = 0;
|
||||
unsigned char ucvar = 0;
|
||||
char cvar = 0;
|
||||
float fvar = 0;
|
||||
double dvar = 0;
|
||||
char *strvar = 0;
|
||||
const char cstrvar[] = "Goodbye";
|
||||
int *iptrvar = 0;
|
||||
char name[256] = "Dave";
|
||||
char path[256] = "/home/beazley";
|
||||
|
||||
|
||||
/* Global variables involving a structure */
|
||||
Point *ptptr = 0;
|
||||
Point pt = { 10, 20 };
|
||||
|
||||
/* A variable that we will make read-only in the interface */
|
||||
int status = 1;
|
||||
|
||||
/* A debugging function to print out their values */
|
||||
|
||||
void print_vars() {
|
||||
printf("ivar = %d\n", ivar);
|
||||
printf("svar = %d\n", svar);
|
||||
printf("lvar = %ld\n", lvar);
|
||||
printf("uivar = %u\n", uivar);
|
||||
printf("usvar = %u\n", usvar);
|
||||
printf("ulvar = %lu\n", ulvar);
|
||||
printf("scvar = %d\n", scvar);
|
||||
printf("ucvar = %u\n", ucvar);
|
||||
printf("fvar = %g\n", fvar);
|
||||
printf("dvar = %g\n", dvar);
|
||||
printf("cvar = %c\n", cvar);
|
||||
printf("strvar = %s\n", strvar ? strvar : "(null)");
|
||||
printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)");
|
||||
printf("iptrvar = %p\n", iptrvar);
|
||||
printf("name = %s\n", name);
|
||||
printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0);
|
||||
printf("pt = (%d, %d)\n", pt.x, pt.y);
|
||||
printf("status = %d\n", status);
|
||||
}
|
||||
|
||||
/* A function to create an integer (to test iptrvar) */
|
||||
|
||||
int *new_int(int value) {
|
||||
int *ip = (int *) malloc(sizeof(int));
|
||||
*ip = value;
|
||||
return ip;
|
||||
}
|
||||
|
||||
/* A function to create a point */
|
||||
|
||||
Point *new_Point(int x, int y) {
|
||||
Point *p = (Point *) malloc(sizeof(Point));
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
return p;
|
||||
}
|
||||
|
||||
char * Point_print(Point *p) {
|
||||
static char buffer[256];
|
||||
if (p) {
|
||||
sprintf(buffer,"(%d, %d)", p->x,p->y);
|
||||
} else {
|
||||
sprintf(buffer,"null");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void pt_print() {
|
||||
printf("(%d, %d)\n", pt.x, pt.y);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
/* File: example.h */
|
||||
|
||||
typedef struct {
|
||||
int x,y;
|
||||
} Point;
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Some global variable declarations */
|
||||
%inline %{
|
||||
extern int ivar;
|
||||
extern short svar;
|
||||
extern long lvar;
|
||||
extern unsigned int uivar;
|
||||
extern unsigned short usvar;
|
||||
extern unsigned long ulvar;
|
||||
extern signed char scvar;
|
||||
extern unsigned char ucvar;
|
||||
extern char cvar;
|
||||
extern float fvar;
|
||||
extern double dvar;
|
||||
extern char *strvar;
|
||||
extern const char cstrvar[];
|
||||
extern int *iptrvar;
|
||||
extern char name[256];
|
||||
|
||||
extern Point *ptptr;
|
||||
extern Point pt;
|
||||
%}
|
||||
|
||||
|
||||
/* Some read-only variables */
|
||||
|
||||
%immutable;
|
||||
|
||||
%inline %{
|
||||
extern int status;
|
||||
extern char path[256];
|
||||
%}
|
||||
|
||||
%mutable;
|
||||
|
||||
/* Some helper functions to make it easier to test */
|
||||
%inline %{
|
||||
extern void print_vars();
|
||||
extern int *new_int(int value);
|
||||
extern Point *new_Point(int x, int y);
|
||||
extern char *Point_print(Point *p);
|
||||
extern void pt_print();
|
||||
%}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#######################################################################
|
||||
# Makefile for D test-suite
|
||||
#######################################################################
|
||||
|
||||
LANGUAGE = d
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = ../@top_srcdir@
|
||||
top_builddir = ../@top_builddir@
|
||||
|
||||
ifeq (2,$(D_VERSION))
|
||||
VERSIONSUFFIX = .2
|
||||
else
|
||||
VERSIONSUFFIX = .1
|
||||
endif
|
||||
|
||||
TESTSUFFIX = _runme$(VERSIONSUFFIX).d
|
||||
|
||||
CPP_TEST_CASES = \
|
||||
d_nativepointers \
|
||||
exception_partial_info
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Override some variables from common.mk:
|
||||
|
||||
TARGETSUFFIX = _wrap
|
||||
|
||||
SWIGOPT+=-splitproxy -package $*
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_cpp))
|
||||
+$(run_testcase)
|
||||
|
||||
%.ctest:
|
||||
$(setup)
|
||||
+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_c))
|
||||
+$(run_testcase)
|
||||
|
||||
%.multicpptest:
|
||||
$(setup)
|
||||
+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_multi_cpp))
|
||||
+$(run_testcase)
|
||||
|
||||
# Makes a directory for the testcase if it does not exist
|
||||
setup = \
|
||||
if [ -f $(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) ]; then \
|
||||
echo "$(ACTION)ing testcase $* (with run test) under $(LANGUAGE)" ; \
|
||||
else \
|
||||
echo "$(ACTION)ing testcase $* under $(LANGUAGE)" ; \
|
||||
fi; \
|
||||
if [ ! -d $*$(VERSIONSUFFIX) ]; then \
|
||||
mkdir $*$(VERSIONSUFFIX); \
|
||||
fi; \
|
||||
if [ ! -d $*$(VERSIONSUFFIX)/$* ]; then \
|
||||
mkdir $*$(VERSIONSUFFIX)/$*; \
|
||||
fi
|
||||
|
||||
# Compiles D files then runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.d appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) ]; then \
|
||||
cd $*$(VERSIONSUFFIX) && \
|
||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
DFLAGS='-of$*_runme' \
|
||||
DSRCS='../$(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) $*/*.d' d_compile && \
|
||||
env LD_LIBRARY_PATH=".:$$LD_LIBRARY_PATH" $(RUNTOOL) ./$*_runme; \
|
||||
else \
|
||||
cd $*$(VERSIONSUFFIX) && \
|
||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
DFLAGS='-c' \
|
||||
DSRCS='$*/*.d' d_compile && cd .. ; \
|
||||
fi
|
||||
|
||||
# Clean: remove testcase directories
|
||||
%.clean:
|
||||
@if [ -d $* ]; then \
|
||||
rm -rf $*; \
|
||||
fi
|
|
@ -0,0 +1,7 @@
|
|||
D language module testsuite
|
||||
---------------------------
|
||||
|
||||
Please see ../README for the common readme file.
|
||||
|
||||
By default the D1 version is built, set D_VERSION=2 (in the environment or at
|
||||
the make command line) to run it for D2 instead.
|
|
@ -0,0 +1,25 @@
|
|||
module aggregate_runme;
|
||||
|
||||
import aggregate.aggregate;
|
||||
|
||||
void main() {
|
||||
// Confirm that move() returns correct results under normal use.
|
||||
int result = move(UP);
|
||||
if (result != UP) throw new Exception("UP failed");
|
||||
|
||||
result = move(DOWN);
|
||||
if (result != DOWN) throw new Exception("DOWN failed");
|
||||
|
||||
result = move(LEFT);
|
||||
if (result != LEFT) throw new Exception("LEFT failed");
|
||||
|
||||
result = move(RIGHT);
|
||||
if (result != RIGHT) throw new Exception("RIGHT failed");
|
||||
|
||||
// Confirm that move() raises an exception when the contract is violated.
|
||||
try {
|
||||
move(0);
|
||||
throw new Exception("0 test failed");
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
module aggregate_runme;
|
||||
|
||||
import aggregate.aggregate;
|
||||
|
||||
void main() {
|
||||
// Confirm that move() returns correct results under normal use.
|
||||
int result = move(UP);
|
||||
if (result != UP) throw new Exception("UP failed");
|
||||
|
||||
result = move(DOWN);
|
||||
if (result != DOWN) throw new Exception("DOWN failed");
|
||||
|
||||
result = move(LEFT);
|
||||
if (result != LEFT) throw new Exception("LEFT failed");
|
||||
|
||||
result = move(RIGHT);
|
||||
if (result != RIGHT) throw new Exception("RIGHT failed");
|
||||
|
||||
// Confirm that move() raises an exception when the contract is violated.
|
||||
try {
|
||||
move(0);
|
||||
throw new Exception("0 test failed");
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
module allprotected_runme;
|
||||
|
||||
import allprotected.Klass;
|
||||
import allprotected.ProtectedBase;
|
||||
|
||||
void main() {
|
||||
auto mpb = new MyProtectedBase("MyProtectedBase");
|
||||
mpb.accessProtected();
|
||||
}
|
||||
|
||||
class MyProtectedBase : ProtectedBase {
|
||||
public:
|
||||
this(char[] name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
void accessProtected() {
|
||||
char[] s = virtualMethod();
|
||||
if (s != "ProtectedBase")
|
||||
throw new Exception("Failed");
|
||||
|
||||
Klass k = instanceMethod(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = instanceOverloaded(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = instanceOverloaded(new Klass("xyz"), "abc");
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticMethod(new Klass("abc"));
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticOverloaded(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticOverloaded(new Klass("xyz"), "abc");
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
instanceMemberVariable = 30;
|
||||
int i = instanceMemberVariable;
|
||||
if (i != 30)
|
||||
throw new Exception("Failed");
|
||||
|
||||
staticMemberVariable = 40;
|
||||
i = staticMemberVariable;
|
||||
if (i != 40)
|
||||
throw new Exception("Failed");
|
||||
|
||||
i = staticConstMemberVariable;
|
||||
if (i != 20)
|
||||
throw new Exception("Failed");
|
||||
|
||||
anEnum = ProtectedBase.AnEnum.EnumVal1;
|
||||
ProtectedBase.AnEnum ae = anEnum;
|
||||
if (ae != ProtectedBase.AnEnum.EnumVal1)
|
||||
throw new Exception("Failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
module allprotected_runme;
|
||||
|
||||
import allprotected.Klass;
|
||||
import allprotected.ProtectedBase;
|
||||
|
||||
void main() {
|
||||
auto mpb = new MyProtectedBase("MyProtectedBase");
|
||||
mpb.accessProtected();
|
||||
}
|
||||
|
||||
class MyProtectedBase : ProtectedBase {
|
||||
public:
|
||||
this(string name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
void accessProtected() {
|
||||
string s = virtualMethod();
|
||||
if (s != "ProtectedBase")
|
||||
throw new Exception("Failed");
|
||||
|
||||
Klass k = instanceMethod(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = instanceOverloaded(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = instanceOverloaded(new Klass("xyz"), "abc");
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticMethod(new Klass("abc"));
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticOverloaded(new Klass("xyz"));
|
||||
if (k.getName() != "xyz")
|
||||
throw new Exception("Failed");
|
||||
|
||||
k = staticOverloaded(new Klass("xyz"), "abc");
|
||||
if (k.getName() != "abc")
|
||||
throw new Exception("Failed");
|
||||
|
||||
instanceMemberVariable = 30;
|
||||
int i = instanceMemberVariable;
|
||||
if (i != 30)
|
||||
throw new Exception("Failed");
|
||||
|
||||
staticMemberVariable = 40;
|
||||
i = staticMemberVariable;
|
||||
if (i != 40)
|
||||
throw new Exception("Failed");
|
||||
|
||||
i = staticConstMemberVariable;
|
||||
if (i != 20)
|
||||
throw new Exception("Failed");
|
||||
|
||||
anEnum = ProtectedBase.AnEnum.EnumVal1;
|
||||
ProtectedBase.AnEnum ae = anEnum;
|
||||
if (ae != ProtectedBase.AnEnum.EnumVal1)
|
||||
throw new Exception("Failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
module apply_strings_runme;
|
||||
|
||||
import apply_strings.apply_strings;
|
||||
|
||||
const char[] TEST_MESSAGE = "A message from target language to the C++ world and back again.";
|
||||
|
||||
void main() {
|
||||
if (UCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("UCharFunction failed");
|
||||
if (SCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("SCharFunction failed");
|
||||
auto pChar = CharFunction(null);
|
||||
if (pChar !is null) throw new Exception("CharFunction failed");
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
module apply_strings_runme;
|
||||
|
||||
import apply_strings.apply_strings;
|
||||
|
||||
enum string TEST_MESSAGE = "A message from target language to the C++ world and back again.";
|
||||
|
||||
void main() {
|
||||
if (UCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("UCharFunction failed");
|
||||
if (SCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("SCharFunction failed");
|
||||
auto pChar = CharFunction(null);
|
||||
if (pChar !is null) throw new Exception("CharFunction failed");
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/// This is the bool runtime testcase. It checks that the C++ bool type works.
|
||||
module bools_runme;
|
||||
|
||||
import bools.bools;
|
||||
|
||||
void main() {
|
||||
bool t = true;
|
||||
bool f = false;
|
||||
|
||||
check_bo(f);
|
||||
check_bo(t);
|
||||
}
|
||||
|
||||
void check_bo(bool input) {
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
if (bo(input) != input) {
|
||||
throw new Exception("Runtime test check_bo failed.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/// This is the bool runtime testcase. It checks that the C++ bool type works.
|
||||
module bools_runme;
|
||||
|
||||
import bools.bools;
|
||||
|
||||
void main() {
|
||||
bool t = true;
|
||||
bool f = false;
|
||||
|
||||
check_bo(f);
|
||||
check_bo(t);
|
||||
}
|
||||
|
||||
void check_bo(bool input) {
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
if (bo(input) != input) {
|
||||
throw new Exception("Runtime test check_bo failed.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
module catches_runme;
|
||||
|
||||
import catches.catches;
|
||||
|
||||
void main() {
|
||||
test({ test_catches(1); }, "C++ int exception thrown, value: 1");
|
||||
test({ test_catches(2); }, "two");
|
||||
test({ test_catches(3); }, "C++ ThreeException const & exception thrown");
|
||||
|
||||
test({ test_exception_specification(1); }, "C++ int exception thrown, value: 1");
|
||||
test({ test_exception_specification(2); }, "unknown exception");
|
||||
test({ test_exception_specification(3); }, "unknown exception");
|
||||
|
||||
test({ test_catches_all(1); }, "unknown exception");
|
||||
}
|
||||
|
||||
void test(void delegate() command, char[] expectedMessage) {
|
||||
bool didntThrow;
|
||||
try {
|
||||
command();
|
||||
didntThrow = true;
|
||||
} catch (Exception e) {
|
||||
if (e.msg != expectedMessage) {
|
||||
throw new Exception("Failed to propagate C++ exception. Expected '" ~
|
||||
expectedMessage ~ "', but received '" ~ e.msg ~ "'.");
|
||||
}
|
||||
}
|
||||
|
||||
if (didntThrow) {
|
||||
throw new Exception("Failed to propagate C++ exception. Expected '" ~
|
||||
expectedMessage ~ "', but no exception was thrown.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
module catches_runme;
|
||||
|
||||
import catches.catches;
|
||||
|
||||
void main() {
|
||||
test({ test_catches(1); }, "C++ int exception thrown, value: 1");
|
||||
test({ test_catches(2); }, "two");
|
||||
test({ test_catches(3); }, "C++ ThreeException const & exception thrown");
|
||||
|
||||
test({ test_exception_specification(1); }, "C++ int exception thrown, value: 1");
|
||||
test({ test_exception_specification(2); }, "unknown exception");
|
||||
test({ test_exception_specification(3); }, "unknown exception");
|
||||
|
||||
test({ test_catches_all(1); }, "unknown exception");
|
||||
}
|
||||
|
||||
void test(void delegate() command, string expectedMessage) {
|
||||
bool didntThrow;
|
||||
try {
|
||||
command();
|
||||
didntThrow = true;
|
||||
} catch (Exception e) {
|
||||
if (e.msg != expectedMessage) {
|
||||
throw new Exception("Failed to propagate C++ exception. Expected '" ~
|
||||
expectedMessage ~ "', but received '" ~ e.msg ~ "'.");
|
||||
}
|
||||
}
|
||||
|
||||
if (didntThrow) {
|
||||
throw new Exception("Failed to propagate C++ exception. Expected '" ~
|
||||
expectedMessage ~ "', but no exception was thrown.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
module char_strings_runme;
|
||||
|
||||
import tango.text.convert.Integer;
|
||||
import char_strings.char_strings;
|
||||
|
||||
const char[] CPLUSPLUS_MSG = "A message from the deep dark world of C++, where anything is possible.";
|
||||
const char[] OTHERLAND_MSG = "Little message from the safe world.";
|
||||
|
||||
void main() {
|
||||
const uint count = 10000;
|
||||
uint i = 0;
|
||||
|
||||
// get functions
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetCharHeapString();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char get 1 failed, iteration " ~ toString(i));
|
||||
DeleteCharHeapString();
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetConstCharProgramCodeString();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char get 2 failed, iteration " ~ toString(i));
|
||||
DeleteCharHeapString();
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetCharStaticString();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char get 3 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetCharStaticStringFixed();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char get 4 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetConstCharStaticStringFixed();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char get 5 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
// set functions
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetCharHeapString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 1 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetCharStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 2 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetCharArrayStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 3 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetConstCharHeapString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 4 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetConstCharStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 5 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetConstCharArrayStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 6 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetCharConstStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 7 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetConstCharConstStaticString(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char set 8 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
// get set function
|
||||
for (i=0; i<count*10; i++) {
|
||||
char[] ping = OTHERLAND_MSG ~ toString(i);
|
||||
char[] pong = CharPingPong(ping);
|
||||
if (ping != pong)
|
||||
throw new Exception("Test PingPong 1 failed.\nExpected:" ~ ping ~ "\nReceived:" ~ pong);
|
||||
}
|
||||
|
||||
// variables
|
||||
for (i=0; i<count; i++) {
|
||||
global_char = OTHERLAND_MSG ~ toString(i);
|
||||
if (global_char != OTHERLAND_MSG ~ toString(i))
|
||||
throw new Exception("Test variables 1 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
global_char_array1 = OTHERLAND_MSG ~ toString(i);
|
||||
if (global_char_array1 != OTHERLAND_MSG ~ toString(i))
|
||||
throw new Exception("Test variables 2 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
global_char_array2 = OTHERLAND_MSG ~ toString(i);
|
||||
if (global_char_array2 != OTHERLAND_MSG ~ toString(i))
|
||||
throw new Exception("Test variables 3 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (global_const_char != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test variables 4 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (global_const_char_array1 != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test variables 5 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (global_const_char_array2 != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test variables 6 failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
// char *& tests
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetCharPointerRef();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char pointer ref get failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetCharPointerRef(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test char pointer ref set failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
char[] str = GetConstCharPointerRef();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test const char pointer ref get failed, iteration " ~ toString(i));
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!SetConstCharPointerRef(OTHERLAND_MSG ~ toString(i), i))
|
||||
throw new Exception("Test const char pointer ref set failed, iteration " ~ toString(i));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
module char_strings_runme;
|
||||
|
||||
import std.conv;
|
||||
import std.exception;
|
||||
import std.range;
|
||||
import char_strings.char_strings;
|
||||
|
||||
enum CPLUSPLUS_MSG = "A message from the deep dark world of C++, where anything is possible.";
|
||||
enum OTHERLAND_MSG = "Little message from the safe world.";
|
||||
enum TEST_RANGE = iota(0, 10000);
|
||||
|
||||
void main() {
|
||||
// get functions
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetCharHeapString() == CPLUSPLUS_MSG, "Test char get 1 failed, iteration " ~ to!string(i));
|
||||
DeleteCharHeapString();
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetConstCharProgramCodeString() == CPLUSPLUS_MSG, "Test char get 2 failed, iteration " ~ to!string(i));
|
||||
DeleteCharHeapString();
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetCharStaticString() == CPLUSPLUS_MSG, "Test char get 3 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetCharStaticStringFixed() == CPLUSPLUS_MSG, "Test char get 4 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetConstCharStaticStringFixed() == CPLUSPLUS_MSG, "Test char get 5 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
// set functions
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetCharHeapString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 1 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetCharStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 2 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetCharArrayStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 3 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetConstCharHeapString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 4 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetConstCharStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 5 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetConstCharArrayStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 6 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetCharConstStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 7 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetConstCharConstStaticString(OTHERLAND_MSG ~ to!string(i), i), "Test char set 8 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
// get set function
|
||||
foreach (i; TEST_RANGE) {
|
||||
string ping = OTHERLAND_MSG ~ to!string(i);
|
||||
string pong = CharPingPong(ping);
|
||||
enforce(ping == pong, "Test PingPong 1 failed.\nExpected:" ~ ping ~ "\nReceived:" ~ pong);
|
||||
}
|
||||
|
||||
// variables
|
||||
foreach (i; TEST_RANGE) {
|
||||
const msg = OTHERLAND_MSG ~ to!string(i);
|
||||
global_char = msg;
|
||||
enforce(global_char == msg, "Test variables 1 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
const msg = OTHERLAND_MSG ~ to!string(i);
|
||||
global_char_array1 = msg;
|
||||
enforce(global_char_array1 == msg, "Test variables 2 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
const msg = OTHERLAND_MSG ~ to!string(i);
|
||||
global_char_array2 = msg;
|
||||
enforce(global_char_array2 == msg, "Test variables 2 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(global_const_char == CPLUSPLUS_MSG, "Test variables 4 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(global_const_char_array1 == CPLUSPLUS_MSG, "Test variables 5 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(global_const_char_array2 == CPLUSPLUS_MSG, "Test variables 6 failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
// char *& tests
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetCharPointerRef() == CPLUSPLUS_MSG, "Test char pointer ref get failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetCharPointerRef(OTHERLAND_MSG ~ to!string(i), i), "Test char pointer ref set failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(GetConstCharPointerRef() == CPLUSPLUS_MSG, "Test const char pointer ref get failed, iteration " ~ to!string(i));
|
||||
}
|
||||
|
||||
foreach (i; TEST_RANGE) {
|
||||
enforce(SetConstCharPointerRef(OTHERLAND_MSG ~ to!string(i), i), "Test const char pointer ref set failed, iteration " ~ to!string(i));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
module constover_runme;
|
||||
|
||||
import constover.constover;
|
||||
import constover.Foo;
|
||||
|
||||
void main() {
|
||||
char[] p = test("test");
|
||||
if (p != "test")
|
||||
throw new Exception("test failed!");
|
||||
|
||||
p = test_pconst("test");
|
||||
if (p != "test_pconst")
|
||||
throw new Exception("test_pconst failed!");
|
||||
|
||||
auto f = new Foo();
|
||||
p = f.test("test");
|
||||
if (p != "test")
|
||||
throw new Exception("member-test failed!");
|
||||
|
||||
p = f.test_pconst("test");
|
||||
if (p != "test_pconst")
|
||||
throw new Exception("member-test_pconst failed!");
|
||||
|
||||
p = f.test_constm("test");
|
||||
if (p != "test_constmethod")
|
||||
throw new Exception("member-test_constm failed!");
|
||||
|
||||
p = f.test_pconstm("test");
|
||||
if (p != "test_pconstmethod")
|
||||
throw new Exception("member-test_pconstm failed!");
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
module constover_runme;
|
||||
|
||||
import std.exception;
|
||||
import constover.constover;
|
||||
import constover.Foo;
|
||||
|
||||
void main() {
|
||||
enforce(test("test") == "test", "test failed!");
|
||||
enforce(test_pconst("test") == "test_pconst", "test_pconst failed!");
|
||||
|
||||
auto f = new Foo();
|
||||
enforce(f.test("test") == "test", "member-test failed!");
|
||||
enforce(f.test_pconst("test") == "test_pconst", "member-test_pconst failed!");
|
||||
enforce(f.test_constm("test") == "test_constmethod", "member-test_constm failed!");
|
||||
enforce(f.test_pconstm("test") == "test_pconstmethod", "member-test_pconstm failed!");
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
module d_nativepointers_runnme;
|
||||
|
||||
import d_nativepointers.d_nativepointers;
|
||||
import d_nativepointers.SomeClass;
|
||||
import d_nativepointers.SWIGTYPE_p_OpaqueClass;
|
||||
import d_nativepointers.SWIGTYPE_p_p_SomeClass;
|
||||
import d_nativepointers.SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void;
|
||||
|
||||
void main() {
|
||||
check!(a, int*);
|
||||
check!(b, float**);
|
||||
check!(c, char***);
|
||||
check!(d, SomeClass);
|
||||
check!(e, SWIGTYPE_p_p_SomeClass);
|
||||
check!(f, SWIGTYPE_p_OpaqueClass);
|
||||
check!(g, void function(int**, char***));
|
||||
check!(h, SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void);
|
||||
}
|
||||
|
||||
void check(alias F, T)() {
|
||||
static assert(is(T function(T) == typeof(&F)));
|
||||
assert(F(null) is null);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
module d_nativepointers_runnme;
|
||||
|
||||
import d_nativepointers.d_nativepointers;
|
||||
import d_nativepointers.SomeClass;
|
||||
import d_nativepointers.SWIGTYPE_p_OpaqueClass;
|
||||
import d_nativepointers.SWIGTYPE_p_p_SomeClass;
|
||||
import d_nativepointers.SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void;
|
||||
|
||||
void main() {
|
||||
check!(a, int*);
|
||||
check!(b, float**);
|
||||
check!(c, char***);
|
||||
check!(d, SomeClass);
|
||||
check!(e, SWIGTYPE_p_p_SomeClass);
|
||||
check!(f, SWIGTYPE_p_OpaqueClass);
|
||||
check!(g, void function(int**, char***));
|
||||
check!(h, SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void);
|
||||
}
|
||||
|
||||
void check(alias F, T)() {
|
||||
static assert(is(T function(T) == typeof(&F)));
|
||||
assert(F(null) is null);
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
module default_args_runme;
|
||||
|
||||
import default_args.default_args;
|
||||
import default_args.ConstMethods;
|
||||
import default_args.EnumClass;
|
||||
import default_args.Except;
|
||||
import default_args.Foo;
|
||||
import default_args.Klass;
|
||||
import default_args.Statics;
|
||||
import default_args.Tricky;
|
||||
|
||||
void main() {
|
||||
if (anonymous() != 7771)
|
||||
throw new Exception("anonymous (1) failed");
|
||||
if (anonymous(1234) != 1234)
|
||||
throw new Exception("anonymous (2) failed");
|
||||
|
||||
if (booltest() != true)
|
||||
throw new Exception("booltest (1) failed");
|
||||
if (booltest(true) != true)
|
||||
throw new Exception("booltest (2) failed");
|
||||
if (booltest(false) != false)
|
||||
throw new Exception("booltest (3) failed");
|
||||
|
||||
auto ec = new EnumClass();
|
||||
if (ec.blah() != true)
|
||||
throw new Exception("EnumClass failed");
|
||||
|
||||
if (casts1() != null)
|
||||
throw new Exception("casts1 failed");
|
||||
|
||||
if (casts2() != "Hello")
|
||||
throw new Exception("casts2 failed");
|
||||
|
||||
if (casts1("Ciao") != "Ciao")
|
||||
throw new Exception("casts1 not default failed");
|
||||
|
||||
if (chartest1() != 'x')
|
||||
throw new Exception("chartest1 failed");
|
||||
|
||||
if (chartest2() != '\0')
|
||||
throw new Exception("chartest2 failed");
|
||||
|
||||
if (chartest1('y') != 'y')
|
||||
throw new Exception("chartest1 not default failed");
|
||||
|
||||
if (chartest1('y') != 'y')
|
||||
throw new Exception("chartest1 not default failed");
|
||||
|
||||
if (reftest1() != 42)
|
||||
throw new Exception("reftest1 failed");
|
||||
|
||||
if (reftest1(400) != 400)
|
||||
throw new Exception("reftest1 not default failed");
|
||||
|
||||
if (reftest2() != "hello")
|
||||
throw new Exception("reftest2 failed");
|
||||
|
||||
// rename
|
||||
auto foo = new Foo();
|
||||
foo.newname();
|
||||
foo.newname(10);
|
||||
foo.renamed3arg(10, 10.0);
|
||||
foo.renamed2arg(10);
|
||||
foo.renamed1arg();
|
||||
|
||||
// exception specifications
|
||||
testException( { exceptionspec(); }, "exceptionspec 1" );
|
||||
testException( { exceptionspec(-1); }, "exceptionspec 2" );
|
||||
testException( { exceptionspec(100); }, "exceptionspec 3" );
|
||||
|
||||
auto ex = new Except(false);
|
||||
testException( { ex.exspec(); }, "exspec 1" );
|
||||
testException( { ex.exspec(-1); }, "exspec 2" );
|
||||
testException( { ex.exspec(100); }, "exspec 3" );
|
||||
testException( { ex = new Except(true); }, "Except constructor 1" );
|
||||
testException( { ex = new Except(true, -2); }, "Except constructor 2" );
|
||||
|
||||
// Default parameters in static class methods
|
||||
if (Statics.staticmethod() != 10+20+30)
|
||||
throw new Exception("staticmethod 1 failed");
|
||||
if (Statics.staticmethod(100) != 100+20+30)
|
||||
throw new Exception("staticmethod 2 failed");
|
||||
if (Statics.staticmethod(100,200,300) != 100+200+300)
|
||||
throw new Exception("staticmethod 3 failed");
|
||||
|
||||
|
||||
auto tricky = new Tricky();
|
||||
if (tricky.privatedefault() != 200)
|
||||
throw new Exception("privatedefault failed");
|
||||
if (tricky.protectedint() != 2000)
|
||||
throw new Exception("protectedint failed");
|
||||
if (tricky.protecteddouble() != 987.654)
|
||||
throw new Exception("protecteddouble failed");
|
||||
if (tricky.functiondefault() != 500)
|
||||
throw new Exception("functiondefault failed");
|
||||
if (tricky.contrived() != 'X')
|
||||
throw new Exception("contrived failed");
|
||||
|
||||
if (constructorcall().val != -1)
|
||||
throw new Exception("constructorcall test 1 failed");
|
||||
|
||||
if (constructorcall(new Klass(2222)).val != 2222)
|
||||
throw new Exception("constructorcall test 2 failed");
|
||||
|
||||
if (constructorcall(new Klass()).val != -1)
|
||||
throw new Exception("constructorcall test 3 failed");
|
||||
|
||||
// const methods
|
||||
auto cm = new ConstMethods();
|
||||
if (cm.coo() != 20)
|
||||
throw new Exception("coo test 1 failed");
|
||||
if (cm.coo(1.0) != 20)
|
||||
throw new Exception("coo test 2 failed");
|
||||
}
|
||||
|
||||
void testException(void delegate() command, char[] testName) {
|
||||
bool didntThrow;
|
||||
try {
|
||||
command();
|
||||
didntThrow = true;
|
||||
} catch (Exception e) {}
|
||||
|
||||
if (didntThrow) {
|
||||
throw new Exception(testName ~ " failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
module default_args_runme;
|
||||
|
||||
import std.exception;
|
||||
import default_args.default_args;
|
||||
import default_args.ConstMethods;
|
||||
import default_args.EnumClass;
|
||||
import default_args.Except;
|
||||
import default_args.Foo;
|
||||
import default_args.Klass;
|
||||
import default_args.Statics;
|
||||
import default_args.Tricky;
|
||||
|
||||
void main() {
|
||||
enforce(anonymous() == 7771, "anonymous (1) failed");
|
||||
enforce(anonymous(1234) == 1234,"anonymous (2) failed");
|
||||
enforce(booltest() == true, "booltest (1) failed");
|
||||
enforce(booltest(true) == true, "booltest (2) failed");
|
||||
enforce(booltest(false) == false, "booltest (3) failed");
|
||||
enforce((new EnumClass()).blah() == true, "EnumClass failed");
|
||||
enforce(casts1() == null, "casts1 failed");
|
||||
enforce(casts2() == "Hello", "casts2 failed");
|
||||
enforce(casts1("Ciao") == "Ciao", "casts1 not default failed");
|
||||
enforce(chartest1() == 'x', "chartest1 failed");
|
||||
enforce(chartest2() == '\0', "chartest2 failed");
|
||||
enforce(chartest1('y') == 'y', "chartest1 not default failed");
|
||||
enforce(chartest1('y') == 'y', "chartest1 not default failed");
|
||||
enforce(reftest1() == 42, "reftest1 failed");
|
||||
enforce(reftest1(400) == 400, "reftest1 not default failed");
|
||||
enforce(reftest2() == "hello", "reftest2 failed");
|
||||
|
||||
// rename
|
||||
auto foo = new Foo();
|
||||
foo.newname();
|
||||
foo.newname(10);
|
||||
foo.renamed3arg(10, 10.0);
|
||||
foo.renamed2arg(10);
|
||||
foo.renamed1arg();
|
||||
|
||||
// exception specifications
|
||||
enforceThrows( (){ exceptionspec(); }, "exceptionspec 1" );
|
||||
enforceThrows( (){ exceptionspec(-1); }, "exceptionspec 2" );
|
||||
enforceThrows( (){ exceptionspec(100); }, "exceptionspec 3" );
|
||||
|
||||
auto ex = new Except(false);
|
||||
enforceThrows( (){ ex.exspec(); }, "exspec 1" );
|
||||
enforceThrows( (){ ex.exspec(-1); }, "exspec 2" );
|
||||
enforceThrows( (){ ex.exspec(100); }, "exspec 3" );
|
||||
enforceThrows( (){ ex = new Except(true); }, "Except constructor 1" );
|
||||
enforceThrows( (){ ex = new Except(true, -2); }, "Except constructor 2" );
|
||||
|
||||
// Default parameters in static class methods
|
||||
enforce(Statics.staticmethod() == 10+20+30, "staticmethod 1 failed");
|
||||
enforce(Statics.staticmethod(100) == 100+20+30, "staticmethod 2 failed");
|
||||
enforce(Statics.staticmethod(100,200,300) == 100+200+300, "staticmethod 3 failed");
|
||||
|
||||
auto tricky = new Tricky();
|
||||
enforce(tricky.privatedefault() == 200, "privatedefault failed");
|
||||
enforce(tricky.protectedint() == 2000, "protectedint failed");
|
||||
enforce(tricky.protecteddouble() == 987.654, "protecteddouble failed");
|
||||
enforce(tricky.functiondefault() == 500, "functiondefault failed");
|
||||
enforce(tricky.contrived() == 'X', "contrived failed");
|
||||
|
||||
enforce(constructorcall().val == -1, "constructorcall test 1 failed");
|
||||
enforce(constructorcall(new Klass(2222)).val == 2222, "constructorcall test 2 failed");
|
||||
enforce(constructorcall(new Klass()).val == -1, "constructorcall test 3 failed");
|
||||
|
||||
// const methods
|
||||
const cm = new ConstMethods();
|
||||
enforce(cm.coo() == 20, "coo test 1 failed");
|
||||
enforce(cm.coo(1.0) == 20, "coo test 2 failed");
|
||||
}
|
||||
|
||||
private void enforceThrows(void delegate() dg, string errorMessage) {
|
||||
bool hasThrown;
|
||||
try {
|
||||
dg();
|
||||
} catch (Exception) {
|
||||
hasThrown = true;
|
||||
} finally {
|
||||
if (!hasThrown) {
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
module default_constructor_runme;
|
||||
|
||||
import default_constructor.FFF;
|
||||
import default_constructor.G;
|
||||
|
||||
void main() {
|
||||
// Protected destructor test.
|
||||
try {
|
||||
{
|
||||
scope g = new G();
|
||||
}
|
||||
throw new Exception("Protected destructor exception should have been thrown");
|
||||
} catch (Exception e) {
|
||||
if (e.msg != "C++ destructor does not have public access") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Private destructor test.
|
||||
try {
|
||||
{
|
||||
scope f = new FFF();
|
||||
}
|
||||
throw new Exception("Private destructor exception should have been thrown");
|
||||
} catch (Exception e) {
|
||||
if (e.msg != "C++ destructor does not have public access") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
module default_constructor_runme;
|
||||
|
||||
import default_constructor.FFF;
|
||||
import default_constructor.G;
|
||||
|
||||
void main() {
|
||||
// D2 does not support something akin to D1/Tango dispose() for deterministic
|
||||
// destruction yet.
|
||||
|
||||
// enforceThrows((){ scope g = new G(); }, "Protected destructor exception should have been thrown");
|
||||
// enforceThrows((){ scope f = new FFF(); }, "Private destructor exception should have been thrown");
|
||||
}
|
||||
|
||||
private void enforceThrows(void delegate() dg, string errorMessage) {
|
||||
bool hasThrown;
|
||||
try {
|
||||
dg();
|
||||
} catch (Exception) {
|
||||
hasThrown = true;
|
||||
} finally {
|
||||
if (!hasThrown) {
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
module director_basic_runme;
|
||||
|
||||
import director_basic.A1;
|
||||
import director_basic.Bar;
|
||||
import director_basic.Foo;
|
||||
import director_basic.MyClass;
|
||||
|
||||
void main() {
|
||||
auto a = new director_basic_MyFoo();
|
||||
if (a.ping() != "director_basic_MyFoo::ping()") {
|
||||
throw new Exception("a.ping()");
|
||||
}
|
||||
if (a.pong() != "Foo::pong();director_basic_MyFoo::ping()") {
|
||||
throw new Exception("a.pong()");
|
||||
}
|
||||
|
||||
auto b = new Foo();
|
||||
if (b.ping() != "Foo::ping()") {
|
||||
throw new Exception("b.ping()");
|
||||
}
|
||||
if (b.pong() != "Foo::pong();Foo::ping()") {
|
||||
throw new Exception("b.pong()");
|
||||
}
|
||||
|
||||
{
|
||||
scope a1 = new A1(1, false);
|
||||
}
|
||||
|
||||
{
|
||||
auto my = new MyOverriddenClass();
|
||||
|
||||
my.expectNull = true;
|
||||
if (MyClass.call_pmethod(my, null) !is null)
|
||||
throw new Exception("null pointer conversion problem");
|
||||
|
||||
auto myBar = new Bar();
|
||||
my.expectNull = false;
|
||||
auto myNewBar = MyClass.call_pmethod(my, myBar);
|
||||
if (myNewBar is null)
|
||||
throw new Exception("non-null pointer conversion problem");
|
||||
myNewBar.x = 10;
|
||||
}
|
||||
}
|
||||
|
||||
class director_basic_MyFoo : Foo {
|
||||
public override char[] ping() {
|
||||
return "director_basic_MyFoo::ping()";
|
||||
}
|
||||
}
|
||||
|
||||
class MyOverriddenClass : MyClass {
|
||||
public bool expectNull = false;
|
||||
public bool nonNullReceived = false;
|
||||
public override Bar pmethod(Bar b) {
|
||||
if (expectNull && (b !is null))
|
||||
throw new Exception("null not received as expected");
|
||||
return b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
module director_basic_runme;
|
||||
|
||||
import std.exception;
|
||||
import director_basic.A1;
|
||||
import director_basic.Bar;
|
||||
import director_basic.Foo;
|
||||
import director_basic.MyClass;
|
||||
|
||||
void main() {
|
||||
auto a = new director_basic_MyFoo();
|
||||
enforce(a.ping() == "director_basic_MyFoo::ping()", "a.ping()");
|
||||
enforce(a.pong() == "Foo::pong();director_basic_MyFoo::ping()", "a.pong()");
|
||||
|
||||
auto b = new Foo();
|
||||
enforce(b.ping() == "Foo::ping()", "b.ping()");
|
||||
enforce(b.pong() == "Foo::pong();Foo::ping()", "b.pong()");
|
||||
|
||||
{
|
||||
scope a1 = new A1(1, false);
|
||||
}
|
||||
|
||||
auto my = new MyOverriddenClass();
|
||||
my.expectNull = true;
|
||||
enforce(MyClass.call_pmethod(my, null) is null, "null pointer conversion problem");
|
||||
auto myBar = new Bar();
|
||||
my.expectNull = false;
|
||||
auto myNewBar = MyClass.call_pmethod(my, myBar);
|
||||
enforce(myNewBar !is null, "non-null pointer conversion problem");
|
||||
myNewBar.x = 10;
|
||||
}
|
||||
|
||||
class director_basic_MyFoo : Foo {
|
||||
public override string ping() {
|
||||
return "director_basic_MyFoo::ping()";
|
||||
}
|
||||
}
|
||||
|
||||
class MyOverriddenClass : MyClass {
|
||||
public bool expectNull = false;
|
||||
public bool nonNullReceived = false;
|
||||
public override Bar pmethod(Bar b) {
|
||||
if (expectNull && (b !is null))
|
||||
throw new Exception("null not received as expected");
|
||||
return b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* This test demonstrates director classes when the types are classes. Shown are
|
||||
* virtual function calls which use classes passed by
|
||||
* - Value
|
||||
* - Reference
|
||||
* - Pointer
|
||||
* as both parameters and return values
|
||||
*
|
||||
* The test also demonstrates directors used with:
|
||||
* - method overloading
|
||||
* - default parameters
|
||||
*
|
||||
* Note: Methods with default parameters that call up from C++ cannot call the
|
||||
* overloaded D methods, see DefaultParms method.
|
||||
|
||||
* Expected output if PrintDebug enabled:
|
||||
* ------------ Start ------------
|
||||
* Base - Val(444.555)
|
||||
* Base - Ref(444.555)
|
||||
* Base - Ptr(444.555)
|
||||
* Base - FullyOverloaded(int 10)
|
||||
* Base - FullyOverloaded(bool 1)
|
||||
* Base - SemiOverloaded(int -678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* Base - DefaultParms(10, 2.2)
|
||||
* Base - DefaultParms(10, 1.1)
|
||||
* --------------------------------
|
||||
* Derived - Val(444.555)
|
||||
* Derived - Ref(444.555)
|
||||
* Derived - Ptr(444.555)
|
||||
* Derived - FullyOverloaded(int 10)
|
||||
* Derived - FullyOverloaded(bool 1)
|
||||
* Derived - SemiOverloaded(int -678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* Derived - DefaultParms(10, 2.2)
|
||||
* Derived - DefaultParms(10, 1.1)
|
||||
* --------------------------------
|
||||
* DDerived - Val(444.555)
|
||||
* DDerived - Ref(444.555)
|
||||
* DDerived - Ptr(444.555)
|
||||
* DDerived - FullyOverloaded(int 10)
|
||||
* DDerived - FullyOverloaded(bool True)
|
||||
* DDerived - SemiOverloaded(-678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* DDerived - DefaultParms(10, 2.2)
|
||||
* DDerived - DefaultParms(10, 1.1)
|
||||
* ------------ Finish ------------
|
||||
*/
|
||||
module director_classes_runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import tango.text.Util;
|
||||
import director_classes.director_classes;
|
||||
import director_classes.Caller;
|
||||
import director_classes.Base;
|
||||
import director_classes.Derived;
|
||||
import director_classes.DoubleHolder;
|
||||
|
||||
void main() {
|
||||
if (PrintDebug) Stdout.formatln("------------ Start ------------ ");
|
||||
|
||||
auto myCaller = new Caller();
|
||||
|
||||
// Test C++ base class.
|
||||
{
|
||||
scope myBase = new Base(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout.formatln("--------------------------------");
|
||||
|
||||
// Test vanilla C++ wrapped derived class.
|
||||
{
|
||||
scope myBase = new Derived(200.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout.formatln("--------------------------------");
|
||||
|
||||
// Test director / D derived class.
|
||||
{
|
||||
scope myBase = new DDerived(300.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout.formatln("------------ Finish ------------ ");
|
||||
}
|
||||
|
||||
void makeCalls(Caller myCaller, Base myBase) {
|
||||
char[] myBaseType = myBase.classinfo.name.split(".")[$-1];
|
||||
myCaller.set(myBase);
|
||||
|
||||
DoubleHolder dh = new DoubleHolder(444.555);
|
||||
|
||||
// Class pointer, reference and pass by value tests
|
||||
if (myCaller.ValCall(dh).val != dh.val) throw new Exception("[1] failed");
|
||||
if (myCaller.RefCall(dh).val != dh.val) throw new Exception("[2] failed");
|
||||
if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("[3] failed");
|
||||
|
||||
// Fully overloaded method test (all methods in base class are overloaded)
|
||||
if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
|
||||
if (myCaller.FullyOverloadedCall(true) != myBaseType ~ "::FullyOverloaded(bool)") throw new Exception("[5] failed");
|
||||
|
||||
// Semi overloaded method test (some methods in base class are overloaded)
|
||||
if (myCaller.SemiOverloadedCall(-678) != myBaseType ~ "::SemiOverloaded(int)") throw new Exception("[6] failed");
|
||||
if (myCaller.SemiOverloadedCall(true) != "Base" ~ "::SemiOverloaded(bool)") throw new Exception("[7] failed");
|
||||
|
||||
// Default parameters methods test
|
||||
if (myCaller.DefaultParmsCall(10, 2.2) != myBaseType ~ "::DefaultParms(int, double)") throw new Exception("[8] failed");
|
||||
if (myBase.classinfo == DDerived.classinfo) { // special handling for D derived classes, there is no way to do this any other way
|
||||
if (myCaller.DefaultParmsCall(10) != myBaseType ~ "::DefaultParms(int, double)") throw new Exception("[9] failed");
|
||||
} else {
|
||||
if (myCaller.DefaultParmsCall(10) != myBaseType ~ "::DefaultParms(int)") throw new Exception("[10] failed");
|
||||
}
|
||||
|
||||
myCaller.reset();
|
||||
}
|
||||
|
||||
public class DDerived : Base {
|
||||
public this(double dd) {
|
||||
super(dd);
|
||||
}
|
||||
|
||||
public override DoubleHolder Val(DoubleHolder x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - Val({0:d3})", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override DoubleHolder Ref(DoubleHolder x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - Ref({0:d3})", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override DoubleHolder Ptr(DoubleHolder x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - Ptr({0:d3})", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override char[] FullyOverloaded(int x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
|
||||
return "DDerived::FullyOverloaded(int)";
|
||||
}
|
||||
|
||||
public override char[] FullyOverloaded(bool x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(bool {0})", x);
|
||||
return "DDerived::FullyOverloaded(bool)";
|
||||
}
|
||||
|
||||
public override char[] SemiOverloaded(int x) {
|
||||
char[] ret = "DDerived::SemiOverloaded(int)";
|
||||
if (PrintDebug) Stdout.formatln("DDerived - SemiOverloaded({0})", x);
|
||||
return ret;
|
||||
}
|
||||
alias Base.SemiOverloaded SemiOverloaded; // Alias in SemiOverloaded(bool x).
|
||||
|
||||
public override char[] DefaultParms(int x, double y) {
|
||||
char[] ret = "DDerived::DefaultParms(int, double)";
|
||||
if (PrintDebug) Stdout.formatln("DDerived - DefaultParms({0}, {1:d1})", x, y);
|
||||
return ret;
|
||||
}
|
||||
// This method will never be called from C++ code because the two-parameter
|
||||
// DefaultParams() has a default value for the second parameter there. It is
|
||||
// only here to ensure consistent behavior for calls from C++ and D code.
|
||||
public override char[] DefaultParms(int x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - DefaultParms({0})", x);
|
||||
return DefaultParms(x, 1.1/*use C++ default here*/);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/**
|
||||
* This test demonstrates director classes when the types are classes. Shown are
|
||||
* virtual function calls which use classes passed by
|
||||
* - Value
|
||||
* - Reference
|
||||
* - Pointer
|
||||
* as both parameters and return values
|
||||
*
|
||||
* The test also demonstrates directors used with:
|
||||
* - method overloading
|
||||
* - default parameters
|
||||
*
|
||||
* Note: Methods with default parameters that call up from C++ cannot call the
|
||||
* overloaded D methods, see DefaultParms method.
|
||||
|
||||
* Expected output if PrintDebug enabled:
|
||||
* ------------ Start ------------
|
||||
* Base - Val(444.555)
|
||||
* Base - Ref(444.555)
|
||||
* Base - Ptr(444.555)
|
||||
* Base - FullyOverloaded(int 10)
|
||||
* Base - FullyOverloaded(bool 1)
|
||||
* Base - SemiOverloaded(int -678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* Base - DefaultParms(10, 2.2)
|
||||
* Base - DefaultParms(10, 1.1)
|
||||
* --------------------------------
|
||||
* Derived - Val(444.555)
|
||||
* Derived - Ref(444.555)
|
||||
* Derived - Ptr(444.555)
|
||||
* Derived - FullyOverloaded(int 10)
|
||||
* Derived - FullyOverloaded(bool 1)
|
||||
* Derived - SemiOverloaded(int -678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* Derived - DefaultParms(10, 2.2)
|
||||
* Derived - DefaultParms(10, 1.1)
|
||||
* --------------------------------
|
||||
* DDerived - Val(444.555)
|
||||
* DDerived - Ref(444.555)
|
||||
* DDerived - Ptr(444.555)
|
||||
* DDerived - FullyOverloaded(int 10)
|
||||
* DDerived - FullyOverloaded(bool true)
|
||||
* DDerived - SemiOverloaded(-678)
|
||||
* Base - SemiOverloaded(bool 1)
|
||||
* DDerived - DefaultParms(10, 2.2)
|
||||
* DDerived - DefaultParms(10, 1.1)
|
||||
* ------------ Finish ------------
|
||||
*/
|
||||
module director_classes_runme;
|
||||
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
import director_classes.director_classes;
|
||||
import director_classes.Caller;
|
||||
import director_classes.Base;
|
||||
import director_classes.Derived;
|
||||
import director_classes.DoubleHolder;
|
||||
|
||||
void main() {
|
||||
if (PrintDebug) writeln("------------ Start ------------ ");
|
||||
|
||||
auto myCaller = new Caller();
|
||||
|
||||
// Test C++ base class.
|
||||
{
|
||||
scope myBase = new Base(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("--------------------------------");
|
||||
|
||||
// Test vanilla C++ wrapped derived class.
|
||||
{
|
||||
scope myBase = new Derived(200.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("--------------------------------");
|
||||
|
||||
// Test director / D derived class.
|
||||
{
|
||||
scope myBase = new DDerived(300.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("------------ Finish ------------ ");
|
||||
}
|
||||
|
||||
void makeCalls(Caller myCaller, Base myBase) {
|
||||
string myBaseType = myBase.classinfo.name.split(".")[$-1];
|
||||
myCaller.set(myBase);
|
||||
|
||||
DoubleHolder dh = new DoubleHolder(444.555);
|
||||
|
||||
// Class pointer, reference and pass by value tests
|
||||
enforce(myCaller.ValCall(dh).val == dh.val, "[1] failed");
|
||||
enforce(myCaller.RefCall(dh).val == dh.val, "[2] failed");
|
||||
enforce(myCaller.PtrCall(dh).val == dh.val, "[3] failed");
|
||||
|
||||
// Fully overloaded method test (all methods in base class are overloaded)
|
||||
enforce(myCaller.FullyOverloadedCall(10) == myBaseType ~ "::FullyOverloaded(int)", "[4] failed");
|
||||
enforce(myCaller.FullyOverloadedCall(true) == myBaseType ~ "::FullyOverloaded(bool)", "[5] failed");
|
||||
|
||||
// Semi overloaded method test (some methods in base class are overloaded)
|
||||
enforce(myCaller.SemiOverloadedCall(-678) == myBaseType ~ "::SemiOverloaded(int)", "[6] failed");
|
||||
enforce(myCaller.SemiOverloadedCall(true) == "Base" ~ "::SemiOverloaded(bool)", "[7] failed");
|
||||
|
||||
// Default parameters methods test
|
||||
enforce(myCaller.DefaultParmsCall(10, 2.2) == myBaseType ~ "::DefaultParms(int, double)", "[8] failed");
|
||||
if (myBase.classinfo == DDerived.classinfo) { // special handling for D derived classes, there is no other way to do this
|
||||
enforce(myCaller.DefaultParmsCall(10) == myBaseType ~ "::DefaultParms(int, double)", "[9] failed");
|
||||
} else {
|
||||
enforce(myCaller.DefaultParmsCall(10) == myBaseType ~ "::DefaultParms(int)", "[10] failed");
|
||||
}
|
||||
|
||||
myCaller.reset();
|
||||
}
|
||||
|
||||
public class DDerived : Base {
|
||||
public this(double dd) {
|
||||
super(dd);
|
||||
}
|
||||
|
||||
public override DoubleHolder Val(DoubleHolder x) {
|
||||
if (PrintDebug) writefln("DDerived - Val(%s)", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override DoubleHolder Ref(DoubleHolder x) {
|
||||
if (PrintDebug) writefln("DDerived - Ref(%s)", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override DoubleHolder Ptr(DoubleHolder x) {
|
||||
if (PrintDebug) writefln("DDerived - Ptr(%s)", x.val);
|
||||
return x;
|
||||
}
|
||||
|
||||
public override string FullyOverloaded(int x) {
|
||||
if (PrintDebug) writefln("DDerived - FullyOverloaded(int %s)", x);
|
||||
return "DDerived::FullyOverloaded(int)";
|
||||
}
|
||||
|
||||
public override string FullyOverloaded(bool x) {
|
||||
if (PrintDebug) writefln("DDerived - FullyOverloaded(bool %s)", x);
|
||||
return "DDerived::FullyOverloaded(bool)";
|
||||
}
|
||||
|
||||
public override string SemiOverloaded(int x) {
|
||||
string ret = "DDerived::SemiOverloaded(int)";
|
||||
if (PrintDebug) writefln("DDerived - SemiOverloaded(%s)", x);
|
||||
return ret;
|
||||
}
|
||||
alias Base.SemiOverloaded SemiOverloaded; // Alias in SemiOverloaded(bool x).
|
||||
|
||||
public override string DefaultParms(int x, double y) {
|
||||
string ret = "DDerived::DefaultParms(int, double)";
|
||||
if (PrintDebug) writefln("DDerived - DefaultParms(%s, %s)", x, y);
|
||||
return ret;
|
||||
}
|
||||
// This method will never be called from C++ code because the two-parameter
|
||||
// DefaultParams() has a default value for the second parameter there. It is
|
||||
// only here to ensure consistent behavior for calls from C++ and D code.
|
||||
public override string DefaultParms(int x) {
|
||||
if (PrintDebug) writefln("DDerived - DefaultParms(%s)", x);
|
||||
return DefaultParms(x, 1.1/*use C++ default here*/);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
module director_classic_runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import director_classic.Caller;
|
||||
import director_classic.Person;
|
||||
import director_classic.Child;
|
||||
import director_classic.GrandChild;
|
||||
import director_classic.OrphanPerson;
|
||||
import director_classic.OrphanChild;
|
||||
|
||||
const bool TRACE = false;
|
||||
|
||||
void main() {
|
||||
{
|
||||
scope person = new Person();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new Child();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new GrandChild();
|
||||
check(person, "GrandChild");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangPerson();
|
||||
check(person, "TargetLangPerson");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangChild();
|
||||
check(person, "TargetLangChild");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangGrandChild();
|
||||
check(person, "TargetLangGrandChild");
|
||||
}
|
||||
|
||||
// Semis - don't override id() in target language
|
||||
{
|
||||
scope person = new TargetLangSemiPerson();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangSemiChild();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangSemiGrandChild();
|
||||
check(person, "GrandChild");
|
||||
}
|
||||
|
||||
// Orphans - don't override id() in C++
|
||||
{
|
||||
scope person = new OrphanPerson();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new OrphanChild();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangOrphanPerson();
|
||||
check(person, "TargetLangOrphanPerson");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangOrphanChild();
|
||||
check(person, "TargetLangOrphanChild");
|
||||
}
|
||||
|
||||
// Duals - id() makes an upcall to the base id()
|
||||
{
|
||||
scope person = new TargetLangDualPerson();
|
||||
check(person, "TargetLangDualPerson + Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualChild();
|
||||
check(person, "TargetLangDualChild + Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualGrandChild();
|
||||
check(person, "TargetLangDualGrandChild + GrandChild");
|
||||
}
|
||||
|
||||
// Mix Orphans and Duals
|
||||
{
|
||||
scope person = new TargetLangDualOrphanPerson();
|
||||
check(person, "TargetLangDualOrphanPerson + Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualOrphanChild();
|
||||
check(person, "TargetLangDualOrphanChild + Child");
|
||||
}
|
||||
}
|
||||
|
||||
void check(Person person, char[] expected) {
|
||||
char[] ret;
|
||||
// Normal D polymorphic call.
|
||||
ret = person.id();
|
||||
if (TRACE)
|
||||
Stdout(ret).newline;
|
||||
if (ret != expected)
|
||||
throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
// Polymorphic call from C++.
|
||||
Caller caller = new Caller();
|
||||
caller.setCallback(person);
|
||||
ret = caller.call();
|
||||
if (TRACE)
|
||||
Stdout(ret).newline;
|
||||
if (ret != expected)
|
||||
throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
// Polymorphic call of object created in D and passed to C++ and back again.
|
||||
Person baseclass = caller.baseClass();
|
||||
ret = baseclass.id();
|
||||
if (TRACE)
|
||||
Stdout(ret).newline;
|
||||
if (ret != expected)
|
||||
throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
caller.resetCallback();
|
||||
if (TRACE)
|
||||
Stdout("----------------------------------------").newline;
|
||||
}
|
||||
|
||||
|
||||
// »Full« target language persons.
|
||||
class TargetLangPerson : Person {
|
||||
public override char[] id() {
|
||||
return "TargetLangPerson";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangChild : Child {
|
||||
public override char[] id() {
|
||||
return "TargetLangChild";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangGrandChild : GrandChild {
|
||||
public override char[] id() {
|
||||
return "TargetLangGrandChild";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Semis - don't override id() in target language
|
||||
class TargetLangSemiPerson : Person {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
class TargetLangSemiChild : Child {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
class TargetLangSemiGrandChild : GrandChild {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
|
||||
// Orphans - don't override id() in C++
|
||||
class TargetLangOrphanPerson : OrphanPerson {
|
||||
public override char[] id() {
|
||||
return "TargetLangOrphanPerson";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangOrphanChild : OrphanChild {
|
||||
public override char[] id() {
|
||||
return "TargetLangOrphanChild";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Duals - id() makes an upcall to the base id()
|
||||
class TargetLangDualPerson : Person {
|
||||
public override char[] id() {
|
||||
return "TargetLangDualPerson + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualChild : Child {
|
||||
public override char[] id() {
|
||||
return "TargetLangDualChild + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualGrandChild : GrandChild {
|
||||
public override char[] id() {
|
||||
return "TargetLangDualGrandChild + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mix Orphans and Duals
|
||||
class TargetLangDualOrphanPerson : OrphanPerson {
|
||||
public override char[] id() {
|
||||
return "TargetLangDualOrphanPerson + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualOrphanChild : OrphanChild {
|
||||
public override char[] id() {
|
||||
return "TargetLangDualOrphanChild + " ~ super.id();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
module director_classic_runme;
|
||||
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
import director_classic.Caller;
|
||||
import director_classic.Person;
|
||||
import director_classic.Child;
|
||||
import director_classic.GrandChild;
|
||||
import director_classic.OrphanPerson;
|
||||
import director_classic.OrphanChild;
|
||||
|
||||
enum TRACE = false;
|
||||
|
||||
void main() {
|
||||
{
|
||||
scope person = new Person();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new Child();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new GrandChild();
|
||||
check(person, "GrandChild");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangPerson();
|
||||
check(person, "TargetLangPerson");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangChild();
|
||||
check(person, "TargetLangChild");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangGrandChild();
|
||||
check(person, "TargetLangGrandChild");
|
||||
}
|
||||
|
||||
// Semis - don't override id() in target language
|
||||
{
|
||||
scope person = new TargetLangSemiPerson();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangSemiChild();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangSemiGrandChild();
|
||||
check(person, "GrandChild");
|
||||
}
|
||||
|
||||
// Orphans - don't override id() in C++
|
||||
{
|
||||
scope person = new OrphanPerson();
|
||||
check(person, "Person");
|
||||
}
|
||||
{
|
||||
scope person = new OrphanChild();
|
||||
check(person, "Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangOrphanPerson();
|
||||
check(person, "TargetLangOrphanPerson");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangOrphanChild();
|
||||
check(person, "TargetLangOrphanChild");
|
||||
}
|
||||
|
||||
// Duals - id() makes an upcall to the base id()
|
||||
{
|
||||
scope person = new TargetLangDualPerson();
|
||||
check(person, "TargetLangDualPerson + Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualChild();
|
||||
check(person, "TargetLangDualChild + Child");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualGrandChild();
|
||||
check(person, "TargetLangDualGrandChild + GrandChild");
|
||||
}
|
||||
|
||||
// Mix Orphans and Duals
|
||||
{
|
||||
scope person = new TargetLangDualOrphanPerson();
|
||||
check(person, "TargetLangDualOrphanPerson + Person");
|
||||
}
|
||||
{
|
||||
scope person = new TargetLangDualOrphanChild();
|
||||
check(person, "TargetLangDualOrphanChild + Child");
|
||||
}
|
||||
}
|
||||
|
||||
void check(Person person, string expected) {
|
||||
string ret;
|
||||
// Normal D polymorphic call.
|
||||
ret = person.id();
|
||||
if (TRACE) writeln(ret);
|
||||
enforce(ret == expected, "Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
// Polymorphic call from C++.
|
||||
auto caller = new Caller();
|
||||
caller.setCallback(person);
|
||||
ret = caller.call();
|
||||
if (TRACE) writeln(ret);
|
||||
enforce(ret == expected, "Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
// Polymorphic call of object created in D and passed to C++ and back again.
|
||||
Person baseclass = caller.baseClass();
|
||||
ret = baseclass.id();
|
||||
if (TRACE) writeln(ret);
|
||||
enforce(ret == expected, "Failed. Received: " ~ ret ~ " Expected: " ~ expected);
|
||||
|
||||
caller.resetCallback();
|
||||
if (TRACE)
|
||||
writeln("----------------------------------------");
|
||||
}
|
||||
|
||||
|
||||
// »Full« target language persons.
|
||||
class TargetLangPerson : Person {
|
||||
public override string id() {
|
||||
return "TargetLangPerson";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangChild : Child {
|
||||
public override string id() {
|
||||
return "TargetLangChild";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangGrandChild : GrandChild {
|
||||
public override string id() {
|
||||
return "TargetLangGrandChild";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Semis - don't override id() in target language
|
||||
class TargetLangSemiPerson : Person {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
class TargetLangSemiChild : Child {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
class TargetLangSemiGrandChild : GrandChild {
|
||||
// No id() override
|
||||
}
|
||||
|
||||
|
||||
// Orphans - don't override id() in C++
|
||||
class TargetLangOrphanPerson : OrphanPerson {
|
||||
public override string id() {
|
||||
return "TargetLangOrphanPerson";
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangOrphanChild : OrphanChild {
|
||||
public override string id() {
|
||||
return "TargetLangOrphanChild";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Duals - id() makes an upcall to the base id()
|
||||
class TargetLangDualPerson : Person {
|
||||
public override string id() {
|
||||
return "TargetLangDualPerson + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualChild : Child {
|
||||
public override string id() {
|
||||
return "TargetLangDualChild + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualGrandChild : GrandChild {
|
||||
public override string id() {
|
||||
return "TargetLangDualGrandChild + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mix Orphans and Duals
|
||||
class TargetLangDualOrphanPerson : OrphanPerson {
|
||||
public override string id() {
|
||||
return "TargetLangDualOrphanPerson + " ~ super.id();
|
||||
}
|
||||
}
|
||||
|
||||
class TargetLangDualOrphanChild : OrphanChild {
|
||||
public override string id() {
|
||||
return "TargetLangDualOrphanChild + " ~ super.id();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
module director_ignore_runme;
|
||||
|
||||
import director_ignore.DIgnores;
|
||||
import director_ignore.DAbstractIgnores;
|
||||
|
||||
void main() {
|
||||
// Just check the classes can be instantiated and other methods work as expected
|
||||
auto a = new DIgnoresDerived();
|
||||
if (a.Triple(5) != 15)
|
||||
throw new Exception("Triple failed");
|
||||
|
||||
auto b = new DAbstractIgnoresDerived();
|
||||
if (b.Quadruple(5) != 20)
|
||||
throw new Exception("Quadruple failed");
|
||||
}
|
||||
|
||||
class DIgnoresDerived : DIgnores {
|
||||
public:
|
||||
// These will give a warning if the %ignore is not working
|
||||
int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedMethod(int n) { return 0; }
|
||||
|
||||
int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n) { return 0; }
|
||||
}
|
||||
|
||||
class DAbstractIgnoresDerived : DAbstractIgnores {
|
||||
public:
|
||||
// These will give a warning if the %ignore is not working
|
||||
int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedMethod(int n) { return 0; }
|
||||
|
||||
int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n) { return 0; }
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
module director_ignore_runme;
|
||||
|
||||
import std.exception;
|
||||
import director_ignore.DIgnores;
|
||||
import director_ignore.DAbstractIgnores;
|
||||
|
||||
void main() {
|
||||
// Just check the classes can be instantiated and other methods work as expected
|
||||
auto a = new DIgnoresDerived();
|
||||
enforce(a.Triple(5) == 15, "Triple failed");
|
||||
|
||||
auto b = new DAbstractIgnoresDerived();
|
||||
enforce(b.Quadruple(5) == 20, "Quadruple failed");
|
||||
}
|
||||
|
||||
class DIgnoresDerived : DIgnores {
|
||||
public:
|
||||
// These will give a warning if the %ignore is not working
|
||||
int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedMethod(int n) { return 0; }
|
||||
|
||||
int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n) { return 0; }
|
||||
}
|
||||
|
||||
class DAbstractIgnoresDerived : DAbstractIgnores {
|
||||
public:
|
||||
// These will give a warning if the %ignore is not working
|
||||
int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedMethod(int n) { return 0; }
|
||||
|
||||
int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
|
||||
int OverloadedProtectedMethod(int n) { return 0; }
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* This test program shows a D class DDerived inheriting from Base.
|
||||
*
|
||||
* Three types of classes are created and the virtual methods called to
|
||||
* demonstrate:
|
||||
* - Wide variety of primitive types
|
||||
* - Calling methods with zero, one or more parameters
|
||||
* - Director methods that are not overridden in D
|
||||
* - Director classes that are not overridden at all in D, i.e. non-director
|
||||
* behaviour is as expected for director classes
|
||||
* - Inheritance hierarchy using director methods
|
||||
* - Return types working as well as parameters
|
||||
*
|
||||
* The Caller class is a tester class which calls the virtual functions from C++.
|
||||
*/
|
||||
module director_primitives_runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import director_primitives.director_primitives;
|
||||
import director_primitives.Base;
|
||||
import director_primitives.Caller;
|
||||
import director_primitives.Derived;
|
||||
import director_primitives.HShadowMode;
|
||||
|
||||
void main() {
|
||||
PrintDebug = false;
|
||||
if (PrintDebug) Stdout("------------ Start ------------ ").newline;
|
||||
|
||||
Caller myCaller = new Caller();
|
||||
|
||||
// Test C++ base class.
|
||||
{
|
||||
scope myBase = new Base(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout("--------------------------------").newline;
|
||||
|
||||
// Test vanilla C++ wrapped derived class.
|
||||
{
|
||||
scope Base myBase = new Derived(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout("--------------------------------").newline;
|
||||
|
||||
// Test director/D derived class.
|
||||
{
|
||||
scope Base myBase = new DDerived(300.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) Stdout("------------ Finish ------------ ").newline;
|
||||
}
|
||||
|
||||
void makeCalls(Caller myCaller, Base myBase) {
|
||||
myCaller.set(myBase);
|
||||
|
||||
myCaller.NoParmsMethodCall();
|
||||
if (myCaller.BoolMethodCall(true) != true) throw new Exception("failed");
|
||||
if (myCaller.BoolMethodCall(false) != false) throw new Exception("failed");
|
||||
if (myCaller.IntMethodCall(-123) != -123) throw new Exception("failed");
|
||||
if (myCaller.UIntMethodCall(123) != 123) throw new Exception("failed");
|
||||
if (myCaller.FloatMethodCall(-123.456f) != -123.456f) throw new Exception("failed");
|
||||
if (myCaller.CharPtrMethodCall("test string") != "test string") throw new Exception("failed");
|
||||
if (myCaller.ConstCharPtrMethodCall("another string") != "another string") throw new Exception("failed");
|
||||
if (myCaller.EnumMethodCall(HShadowMode.HShadowHard) != HShadowMode.HShadowHard) throw new Exception("failed");
|
||||
myCaller.ManyParmsMethodCall(true, -123, 123, 123.456f, "test string", "another string", HShadowMode.HShadowHard);
|
||||
myCaller.NotOverriddenMethodCall();
|
||||
|
||||
myCaller.reset();
|
||||
}
|
||||
|
||||
class DDerived : Base {
|
||||
public:
|
||||
this(double dd) {
|
||||
super(dd);
|
||||
}
|
||||
|
||||
override void NoParmsMethod() {
|
||||
if (PrintDebug) Stdout("DDerived - NoParmsMethod()").newline;
|
||||
}
|
||||
|
||||
override bool BoolMethod(bool x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - BoolMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override int IntMethod(int x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - IntMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override uint UIntMethod(uint x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - UIntMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override float FloatMethod(float x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - FloatMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override char[] CharPtrMethod(char[] x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - CharPtrMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override char[] ConstCharPtrMethod(char[] x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - ConstCharPtrMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override HShadowMode EnumMethod(HShadowMode x) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - EnumMethod({0})", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override void ManyParmsMethod(bool b, int i, uint u, float f, char[] c, char[] cc, HShadowMode h) {
|
||||
if (PrintDebug) Stdout.formatln("DDerived - ManyParmsMethod({0}, {1}, {2}, {3:d3}, {4}, {5}, {6})", b, i, u, f, c, cc, h);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* This test program shows a D class DDerived inheriting from Base.
|
||||
*
|
||||
* Three types of classes are created and the virtual methods called to
|
||||
* demonstrate:
|
||||
* - Wide variety of primitive types
|
||||
* - Calling methods with zero, one or more parameters
|
||||
* - Director methods that are not overridden in D
|
||||
* - Director classes that are not overridden at all in D, i.e. non-director
|
||||
* behaviour is as expected for director classes
|
||||
* - Inheritance hierarchy using director methods
|
||||
* - Return types working as well as parameters
|
||||
*
|
||||
* The Caller class is a tester class which calls the virtual functions from C++.
|
||||
*/
|
||||
module director_primitives_runme;
|
||||
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
import director_primitives.director_primitives;
|
||||
import director_primitives.Base;
|
||||
import director_primitives.Caller;
|
||||
import director_primitives.Derived;
|
||||
import director_primitives.HShadowMode;
|
||||
|
||||
void main() {
|
||||
PrintDebug = false;
|
||||
if (PrintDebug) writeln("------------ Start ------------ ");
|
||||
|
||||
auto myCaller = new Caller();
|
||||
|
||||
// Test C++ base class.
|
||||
{
|
||||
scope myBase = new Base(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("--------------------------------");
|
||||
|
||||
// Test vanilla C++ wrapped derived class.
|
||||
{
|
||||
scope Base myBase = new Derived(100.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("--------------------------------");
|
||||
|
||||
// Test director/D derived class.
|
||||
{
|
||||
scope Base myBase = new DDerived(300.0);
|
||||
makeCalls(myCaller, myBase);
|
||||
}
|
||||
|
||||
if (PrintDebug) writeln("------------ Finish ------------ ");
|
||||
}
|
||||
|
||||
void makeCalls(Caller myCaller, Base myBase) {
|
||||
myCaller.set(myBase);
|
||||
|
||||
myCaller.NoParmsMethodCall();
|
||||
enforce(myCaller.BoolMethodCall(true) == true, "failed");
|
||||
enforce(myCaller.BoolMethodCall(false) == false, "failed");
|
||||
enforce(myCaller.IntMethodCall(-123) == -123, "failed");
|
||||
enforce(myCaller.UIntMethodCall(123) == 123, "failed");
|
||||
enforce(myCaller.FloatMethodCall(-123.456f) == -123.456f, "failed");
|
||||
enforce(myCaller.CharPtrMethodCall("test string") == "test string", "failed");
|
||||
enforce(myCaller.ConstCharPtrMethodCall("another string") == "another string", "failed");
|
||||
enforce(myCaller.EnumMethodCall(HShadowMode.HShadowHard) == HShadowMode.HShadowHard, "failed");
|
||||
myCaller.ManyParmsMethodCall(true, -123, 123, 123.456f, "test string", "another string", HShadowMode.HShadowHard);
|
||||
myCaller.NotOverriddenMethodCall();
|
||||
|
||||
myCaller.reset();
|
||||
}
|
||||
|
||||
class DDerived : Base {
|
||||
public:
|
||||
this(double dd) {
|
||||
super(dd);
|
||||
}
|
||||
|
||||
override void NoParmsMethod() {
|
||||
if (PrintDebug) writeln("DDerived - NoParmsMethod()");
|
||||
}
|
||||
|
||||
override bool BoolMethod(bool x) {
|
||||
if (PrintDebug) writefln("DDerived - BoolMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override int IntMethod(int x) {
|
||||
if (PrintDebug) writefln("DDerived - IntMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override uint UIntMethod(uint x) {
|
||||
if (PrintDebug) writefln("DDerived - UIntMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override float FloatMethod(float x) {
|
||||
if (PrintDebug) writefln("DDerived - FloatMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override string CharPtrMethod(string x) {
|
||||
if (PrintDebug) writefln("DDerived - CharPtrMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override string ConstCharPtrMethod(string x) {
|
||||
if (PrintDebug) writefln("DDerived - ConstCharPtrMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override HShadowMode EnumMethod(HShadowMode x) {
|
||||
if (PrintDebug) writefln("DDerived - EnumMethod(%s)", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
override void ManyParmsMethod(bool b, int i, uint u, float f, string c, string cc, HShadowMode h) {
|
||||
if (PrintDebug) writefln("DDerived - ManyParmsMethod(%s, %s, %s, %s, %s, %s, %s)", b, i, u, f, c, cc, h);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
module director_protected_runme;
|
||||
|
||||
import director_protected.Foo;
|
||||
import director_protected.Bar;
|
||||
|
||||
void main() {
|
||||
Bar b = new Bar();
|
||||
Foo f = b.create();
|
||||
auto fb = new FooBar();
|
||||
auto fb2 = new FooBar2();
|
||||
|
||||
char[] s;
|
||||
s = fb.used();
|
||||
if ( s != ("Foo::pang();Bar::pong();Foo::pong();FooBar::ping();"))
|
||||
throw new Exception("bad FooBar::used" ~ " - " ~ s);
|
||||
|
||||
s = fb2.used();
|
||||
if ( s != ("FooBar2::pang();Bar::pong();Foo::pong();FooBar2::ping();"))
|
||||
throw new Exception("bad FooBar2::used");
|
||||
|
||||
s = b.pong();
|
||||
if ( s != ("Bar::pong();Foo::pong();Bar::ping();"))
|
||||
throw new Exception("bad Bar::pong");
|
||||
|
||||
s = f.pong();
|
||||
if ( s != ("Bar::pong();Foo::pong();Bar::ping();"))
|
||||
throw new Exception("bad Foo::pong");
|
||||
|
||||
s = fb.pong();
|
||||
if ( s != ("Bar::pong();Foo::pong();FooBar::ping();"))
|
||||
throw new Exception("bad FooBar::pong");
|
||||
}
|
||||
|
||||
class FooBar : Bar {
|
||||
protected:
|
||||
override char[] ping() {
|
||||
return "FooBar::ping();";
|
||||
}
|
||||
}
|
||||
|
||||
class FooBar2 : Bar{
|
||||
protected:
|
||||
override char[] ping() {
|
||||
return "FooBar2::ping();";
|
||||
}
|
||||
|
||||
override char[] pang() {
|
||||
return "FooBar2::pang();";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
module director_protected_runme;
|
||||
|
||||
import std.exception;
|
||||
import director_protected.Foo;
|
||||
import director_protected.Bar;
|
||||
|
||||
void main() {
|
||||
Bar b = new Bar();
|
||||
Foo f = b.create();
|
||||
auto fb = new FooBar();
|
||||
scope fb2 = new FooBar2();
|
||||
|
||||
enforce(fb.used() == "Foo::pang();Bar::pong();Foo::pong();FooBar::ping();", "bad FooBar::used" ~ " - " ~ fb.used());
|
||||
enforce(fb2.used() == "FooBar2::pang();Bar::pong();Foo::pong();FooBar2::ping();", "bad FooBar2::used");
|
||||
enforce(b.pong() == "Bar::pong();Foo::pong();Bar::ping();", "bad Bar::pong");
|
||||
enforce(f.pong() == "Bar::pong();Foo::pong();Bar::ping();", "bad Foo::pong");
|
||||
enforce(fb.pong() == "Bar::pong();Foo::pong();FooBar::ping();", "bad FooBar::pong");
|
||||
}
|
||||
|
||||
class FooBar : Bar {
|
||||
protected:
|
||||
override string ping() {
|
||||
return "FooBar::ping();";
|
||||
}
|
||||
}
|
||||
|
||||
class FooBar2 : Bar {
|
||||
protected:
|
||||
override string ping() {
|
||||
return "FooBar2::ping();";
|
||||
}
|
||||
|
||||
override string pang() {
|
||||
return "FooBar2::pang();";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
module director_string_runme;
|
||||
|
||||
import Integer = tango.text.convert.Integer;
|
||||
import director_string.A;
|
||||
|
||||
void main() {
|
||||
char[] s;
|
||||
|
||||
auto c = new director_string_A("hi");
|
||||
for (int i=0; i<3; ++i) {
|
||||
s = c.call_get(i);
|
||||
if (s != Integer.toString(i)) throw new Exception("director_string_A.get(" ~ Integer.toString(i) ~ ") failed. Got:" ~ s);
|
||||
}
|
||||
|
||||
auto b = new director_string_B("hello");
|
||||
|
||||
s = b.call_get_first();
|
||||
if (s != "director_string_B.get_first") throw new Exception("call_get_first() failed");
|
||||
|
||||
s = b.call_get(0);
|
||||
if (s != "director_string_B.get: hello") throw new Exception("get(0) failed");
|
||||
}
|
||||
|
||||
class director_string_B : A {
|
||||
public:
|
||||
this(char[] first) {
|
||||
super(first);
|
||||
}
|
||||
override char[] get_first() {
|
||||
return "director_string_B.get_first";
|
||||
}
|
||||
|
||||
override char[] get(int n) {
|
||||
return "director_string_B.get: " ~ super.get(n);
|
||||
}
|
||||
}
|
||||
|
||||
class director_string_A : A {
|
||||
public:
|
||||
this(char[] first) {
|
||||
super(first);
|
||||
}
|
||||
override char[] get(int n) {
|
||||
return Integer.toString(n);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
module director_string_runme;
|
||||
|
||||
import std.conv;
|
||||
import std.exception;
|
||||
import director_string.A;
|
||||
|
||||
void main() {
|
||||
auto c = new director_string_A("hi");
|
||||
for (int i=0; i<3; ++i) {
|
||||
auto s = c.call_get(i);
|
||||
auto expected = to!string(i);
|
||||
enforce(s == expected, "director_string_A.get(" ~ expected ~ ") failed. Got:" ~ s);
|
||||
}
|
||||
|
||||
auto b = new director_string_B("hello");
|
||||
enforce(b.call_get_first() == "director_string_B.get_first", "call_get_first() failed");
|
||||
enforce(b.call_get(0) == "director_string_B.get: hello", "get(0) failed");
|
||||
}
|
||||
|
||||
class director_string_B : A {
|
||||
public:
|
||||
this(string first) {
|
||||
super(first);
|
||||
}
|
||||
override string get_first() const {
|
||||
return "director_string_B.get_first";
|
||||
}
|
||||
|
||||
override string get(int n) const {
|
||||
return "director_string_B.get: " ~ super.get(n);
|
||||
}
|
||||
}
|
||||
|
||||
class director_string_A : A {
|
||||
public:
|
||||
this(string first) {
|
||||
super(first);
|
||||
}
|
||||
override string get(int n) const {
|
||||
return to!string(n);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,424 @@
|
|||
module enum_thorough_runme;
|
||||
|
||||
import enum_thorough.enum_thorough;
|
||||
import enum_thorough.AnonStruct;
|
||||
import enum_thorough.colour;
|
||||
import enum_thorough.FirStruct;
|
||||
import enum_thorough.HairStruct;
|
||||
import enum_thorough.IgnoreTest;
|
||||
import enum_thorough.Instances;
|
||||
import enum_thorough.namedanon;
|
||||
import enum_thorough.namedanonspace;
|
||||
import enum_thorough.newname;
|
||||
import enum_thorough.NewNameStruct;
|
||||
import enum_thorough.repeat;
|
||||
import enum_thorough.SpeedClass;
|
||||
import enum_thorough.TClassInt;
|
||||
import enum_thorough.TemplateClassInt;
|
||||
import enum_thorough.TreesClass;
|
||||
import enum_thorough.twonames;
|
||||
import enum_thorough.TwoNamesStruct;
|
||||
|
||||
void main() {
|
||||
{
|
||||
// Anonymous enums
|
||||
int i = AnonEnum1;
|
||||
if (ReallyAnInteger != 200) throw new Exception("Test Anon 1 failed");
|
||||
i += AnonSpaceEnum1;
|
||||
i += AnonStruct.AnonStructEnum1;
|
||||
}
|
||||
{
|
||||
auto red = colour.red;
|
||||
colourTest1(red);
|
||||
colourTest2(red);
|
||||
colourTest3(red);
|
||||
colourTest4(red);
|
||||
myColour = red;
|
||||
}
|
||||
{
|
||||
auto s = new SpeedClass();
|
||||
auto speed = SpeedClass.speed.slow;
|
||||
if (s.speedTest1(speed) != speed) throw new Exception("speedTest 1 failed");
|
||||
if (s.speedTest2(speed) != speed) throw new Exception("speedTest 2 failed");
|
||||
if (s.speedTest3(speed) != speed) throw new Exception("speedTest 3 failed");
|
||||
if (s.speedTest4(speed) != speed) throw new Exception("speedTest 4 failed");
|
||||
if (s.speedTest5(speed) != speed) throw new Exception("speedTest 5 failed");
|
||||
if (s.speedTest6(speed) != speed) throw new Exception("speedTest 6 failed");
|
||||
if (s.speedTest7(speed) != speed) throw new Exception("speedTest 7 failed");
|
||||
if (s.speedTest8(speed) != speed) throw new Exception("speedTest 8 failed");
|
||||
|
||||
if (speedTest1(speed) != speed) throw new Exception("speedTest Global 1 failed");
|
||||
if (speedTest2(speed) != speed) throw new Exception("speedTest Global 2 failed");
|
||||
if (speedTest3(speed) != speed) throw new Exception("speedTest Global 3 failed");
|
||||
if (speedTest4(speed) != speed) throw new Exception("speedTest Global 4 failed");
|
||||
if (speedTest5(speed) != speed) throw new Exception("speedTest Global 5 failed");
|
||||
}
|
||||
{
|
||||
auto s = new SpeedClass();
|
||||
auto slow = SpeedClass.speed.slow;
|
||||
auto lightning = SpeedClass.speed.lightning;
|
||||
|
||||
if (s.mySpeedtd1 != slow) throw new Exception("mySpeedtd1 1 failed");
|
||||
if (cast(int)s.mySpeedtd1 != 10) throw new Exception("mySpeedtd1 2 failed");
|
||||
|
||||
s.mySpeedtd1 = lightning;
|
||||
if (s.mySpeedtd1 != lightning) throw new Exception("mySpeedtd1 3 failed");
|
||||
if (cast(int)s.mySpeedtd1 != 31) throw new Exception("mySpeedtd1 4 failed");
|
||||
}
|
||||
{
|
||||
if (namedanonTest1(namedanon.NamedAnon2) != namedanon.NamedAnon2) throw new Exception("namedanonTest 1 failed");
|
||||
}
|
||||
{
|
||||
auto val = twonames.TwoNames2;
|
||||
if (twonamesTest1(val) != val) throw new Exception("twonamesTest 1 failed");
|
||||
if (twonamesTest2(val) != val) throw new Exception("twonamesTest 2 failed");
|
||||
if (twonamesTest3(val) != val) throw new Exception("twonamesTest 3 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TwoNamesStruct();
|
||||
auto val = TwoNamesStruct.twonames.TwoNamesStruct1;
|
||||
if (t.twonamesTest1(val) != val) throw new Exception("twonamesTest 1 failed");
|
||||
if (t.twonamesTest2(val) != val) throw new Exception("twonamesTest 2 failed");
|
||||
if (t.twonamesTest3(val) != val) throw new Exception("twonamesTest 3 failed");
|
||||
}
|
||||
{
|
||||
auto val = namedanonspace.NamedAnonSpace2;
|
||||
if (namedanonspaceTest1(val) != val) throw new Exception("namedanonspaceTest 1 failed");
|
||||
if (namedanonspaceTest2(val) != val) throw new Exception("namedanonspaceTest 2 failed");
|
||||
if (namedanonspaceTest3(val) != val) throw new Exception("namedanonspaceTest 3 failed");
|
||||
if (namedanonspaceTest4(val) != val) throw new Exception("namedanonspaceTest 4 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TemplateClassInt();
|
||||
auto galileo = TemplateClassInt.scientists.galileo;
|
||||
if (t.scientistsTest1(galileo) != galileo) throw new Exception("scientistsTest 1 failed");
|
||||
if (t.scientistsTest2(galileo) != galileo) throw new Exception("scientistsTest 2 failed");
|
||||
if (t.scientistsTest3(galileo) != galileo) throw new Exception("scientistsTest 3 failed");
|
||||
if (t.scientistsTest4(galileo) != galileo) throw new Exception("scientistsTest 4 failed");
|
||||
if (t.scientistsTest5(galileo) != galileo) throw new Exception("scientistsTest 5 failed");
|
||||
if (t.scientistsTest6(galileo) != galileo) throw new Exception("scientistsTest 6 failed");
|
||||
if (t.scientistsTest7(galileo) != galileo) throw new Exception("scientistsTest 7 failed");
|
||||
if (t.scientistsTest8(galileo) != galileo) throw new Exception("scientistsTest 8 failed");
|
||||
if (t.scientistsTest9(galileo) != galileo) throw new Exception("scientistsTest 9 failed");
|
||||
// if (t.scientistsTestA(galileo) != galileo) throw new Exception("scientistsTest A failed");
|
||||
if (t.scientistsTestB(galileo) != galileo) throw new Exception("scientistsTest B failed");
|
||||
// if (t.scientistsTestC(galileo) != galileo) throw new Exception("scientistsTest C failed");
|
||||
if (t.scientistsTestD(galileo) != galileo) throw new Exception("scientistsTest D failed");
|
||||
if (t.scientistsTestE(galileo) != galileo) throw new Exception("scientistsTest E failed");
|
||||
if (t.scientistsTestF(galileo) != galileo) throw new Exception("scientistsTest F failed");
|
||||
if (t.scientistsTestG(galileo) != galileo) throw new Exception("scientistsTest G failed");
|
||||
if (t.scientistsTestH(galileo) != galileo) throw new Exception("scientistsTest H failed");
|
||||
if (t.scientistsTestI(galileo) != galileo) throw new Exception("scientistsTest I failed");
|
||||
if (t.scientistsTestJ(galileo) != galileo) throw new Exception("scientistsTest J failed");
|
||||
|
||||
if (scientistsTest1(galileo) != galileo) throw new Exception("scientistsTest Global 1 failed");
|
||||
if (scientistsTest2(galileo) != galileo) throw new Exception("scientistsTest Global 2 failed");
|
||||
if (scientistsTest3(galileo) != galileo) throw new Exception("scientistsTest Global 3 failed");
|
||||
if (scientistsTest4(galileo) != galileo) throw new Exception("scientistsTest Global 4 failed");
|
||||
if (scientistsTest5(galileo) != galileo) throw new Exception("scientistsTest Global 5 failed");
|
||||
if (scientistsTest6(galileo) != galileo) throw new Exception("scientistsTest Global 6 failed");
|
||||
if (scientistsTest7(galileo) != galileo) throw new Exception("scientistsTest Global 7 failed");
|
||||
if (scientistsTest8(galileo) != galileo) throw new Exception("scientistsTest Global 8 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TClassInt();
|
||||
auto bell = TClassInt.scientists.bell;
|
||||
auto galileo = TemplateClassInt.scientists.galileo;
|
||||
if (t.scientistsNameTest1(bell) != bell) throw new Exception("scientistsNameTest 1 failed");
|
||||
if (t.scientistsNameTest2(bell) != bell) throw new Exception("scientistsNameTest 2 failed");
|
||||
if (t.scientistsNameTest3(bell) != bell) throw new Exception("scientistsNameTest 3 failed");
|
||||
if (t.scientistsNameTest4(bell) != bell) throw new Exception("scientistsNameTest 4 failed");
|
||||
if (t.scientistsNameTest5(bell) != bell) throw new Exception("scientistsNameTest 5 failed");
|
||||
if (t.scientistsNameTest6(bell) != bell) throw new Exception("scientistsNameTest 6 failed");
|
||||
if (t.scientistsNameTest7(bell) != bell) throw new Exception("scientistsNameTest 7 failed");
|
||||
if (t.scientistsNameTest8(bell) != bell) throw new Exception("scientistsNameTest 8 failed");
|
||||
if (t.scientistsNameTest9(bell) != bell) throw new Exception("scientistsNameTest 9 failed");
|
||||
// if (t.scientistsNameTestA(bell) != bell) throw new Exception("scientistsNameTest A failed");
|
||||
if (t.scientistsNameTestB(bell) != bell) throw new Exception("scientistsNameTest B failed");
|
||||
// if (t.scientistsNameTestC(bell) != bell) throw new Exception("scientistsNameTest C failed");
|
||||
if (t.scientistsNameTestD(bell) != bell) throw new Exception("scientistsNameTest D failed");
|
||||
if (t.scientistsNameTestE(bell) != bell) throw new Exception("scientistsNameTest E failed");
|
||||
if (t.scientistsNameTestF(bell) != bell) throw new Exception("scientistsNameTest F failed");
|
||||
if (t.scientistsNameTestG(bell) != bell) throw new Exception("scientistsNameTest G failed");
|
||||
if (t.scientistsNameTestH(bell) != bell) throw new Exception("scientistsNameTest H failed");
|
||||
if (t.scientistsNameTestI(bell) != bell) throw new Exception("scientistsNameTest I failed");
|
||||
|
||||
if (t.scientistsNameSpaceTest1(bell) != bell) throw new Exception("scientistsNameSpaceTest 1 failed");
|
||||
if (t.scientistsNameSpaceTest2(bell) != bell) throw new Exception("scientistsNameSpaceTest 2 failed");
|
||||
if (t.scientistsNameSpaceTest3(bell) != bell) throw new Exception("scientistsNameSpaceTest 3 failed");
|
||||
if (t.scientistsNameSpaceTest4(bell) != bell) throw new Exception("scientistsNameSpaceTest 4 failed");
|
||||
if (t.scientistsNameSpaceTest5(bell) != bell) throw new Exception("scientistsNameSpaceTest 5 failed");
|
||||
if (t.scientistsNameSpaceTest6(bell) != bell) throw new Exception("scientistsNameSpaceTest 6 failed");
|
||||
if (t.scientistsNameSpaceTest7(bell) != bell) throw new Exception("scientistsNameSpaceTest 7 failed");
|
||||
|
||||
if (t.scientistsOtherTest1(galileo) != galileo) throw new Exception("scientistsOtherTest 1 failed");
|
||||
if (t.scientistsOtherTest2(galileo) != galileo) throw new Exception("scientistsOtherTest 2 failed");
|
||||
if (t.scientistsOtherTest3(galileo) != galileo) throw new Exception("scientistsOtherTest 3 failed");
|
||||
if (t.scientistsOtherTest4(galileo) != galileo) throw new Exception("scientistsOtherTest 4 failed");
|
||||
if (t.scientistsOtherTest5(galileo) != galileo) throw new Exception("scientistsOtherTest 5 failed");
|
||||
if (t.scientistsOtherTest6(galileo) != galileo) throw new Exception("scientistsOtherTest 6 failed");
|
||||
if (t.scientistsOtherTest7(galileo) != galileo) throw new Exception("scientistsOtherTest 7 failed");
|
||||
|
||||
if (scientistsNameTest1(bell) != bell) throw new Exception("scientistsNameTest Global 1 failed");
|
||||
if (scientistsNameTest2(bell) != bell) throw new Exception("scientistsNameTest Global 2 failed");
|
||||
if (scientistsNameTest3(bell) != bell) throw new Exception("scientistsNameTest Global 3 failed");
|
||||
if (scientistsNameTest4(bell) != bell) throw new Exception("scientistsNameTest Global 4 failed");
|
||||
if (scientistsNameTest5(bell) != bell) throw new Exception("scientistsNameTest Global 5 failed");
|
||||
if (scientistsNameTest6(bell) != bell) throw new Exception("scientistsNameTest Global 6 failed");
|
||||
if (scientistsNameTest7(bell) != bell) throw new Exception("scientistsNameTest Global 7 failed");
|
||||
|
||||
if (scientistsNameSpaceTest1(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 1 failed");
|
||||
if (scientistsNameSpaceTest2(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 2 failed");
|
||||
if (scientistsNameSpaceTest3(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 3 failed");
|
||||
if (scientistsNameSpaceTest4(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 4 failed");
|
||||
if (scientistsNameSpaceTest5(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 5 failed");
|
||||
if (scientistsNameSpaceTest6(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 6 failed");
|
||||
if (scientistsNameSpaceTest7(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 7 failed");
|
||||
|
||||
if (scientistsNameSpaceTest8(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 8 failed");
|
||||
if (scientistsNameSpaceTest9(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 9 failed");
|
||||
if (scientistsNameSpaceTestA(bell) != bell) throw new Exception("scientistsNameSpaceTest Global A failed");
|
||||
if (scientistsNameSpaceTestB(bell) != bell) throw new Exception("scientistsNameSpaceTest Global B failed");
|
||||
if (scientistsNameSpaceTestC(bell) != bell) throw new Exception("scientistsNameSpaceTest Global C failed");
|
||||
if (scientistsNameSpaceTestD(bell) != bell) throw new Exception("scientistsNameSpaceTest Global D failed");
|
||||
if (scientistsNameSpaceTestE(bell) != bell) throw new Exception("scientistsNameSpaceTest Global E failed");
|
||||
|
||||
if (scientistsNameSpaceTestF(bell) != bell) throw new Exception("scientistsNameSpaceTest Global F failed");
|
||||
if (scientistsNameSpaceTestG(bell) != bell) throw new Exception("scientistsNameSpaceTest Global G failed");
|
||||
if (scientistsNameSpaceTestH(bell) != bell) throw new Exception("scientistsNameSpaceTest Global H failed");
|
||||
if (scientistsNameSpaceTestI(bell) != bell) throw new Exception("scientistsNameSpaceTest Global I failed");
|
||||
if (scientistsNameSpaceTestJ(bell) != bell) throw new Exception("scientistsNameSpaceTest Global J failed");
|
||||
if (scientistsNameSpaceTestK(bell) != bell) throw new Exception("scientistsNameSpaceTest Global K failed");
|
||||
if (scientistsNameSpaceTestL(bell) != bell) throw new Exception("scientistsNameSpaceTest Global L failed");
|
||||
}
|
||||
{
|
||||
auto val = newname.argh;
|
||||
if (renameTest1(val) != val) throw new Exception("renameTest Global 1 failed");
|
||||
if (renameTest2(val) != val) throw new Exception("renameTest Global 2 failed");
|
||||
}
|
||||
{
|
||||
auto n = new NewNameStruct();
|
||||
if (n.renameTest1(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest 1 failed");
|
||||
if (n.renameTest2(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest 2 failed");
|
||||
if (n.renameTest3(NewNameStruct.simplerenamed.simple1) != NewNameStruct.simplerenamed.simple1) throw new Exception("renameTest 3 failed");
|
||||
if (n.renameTest4(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest 4 failed");
|
||||
if (n.renameTest5(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest 5 failed");
|
||||
if (n.renameTest6(NewNameStruct.singlenamerenamed.singlename1) != NewNameStruct.singlenamerenamed.singlename1) throw new Exception("renameTest 6 failed");
|
||||
}
|
||||
{
|
||||
if (renameTest3(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest Global 3 failed");
|
||||
if (renameTest4(NewNameStruct.simplerenamed.simple1) != NewNameStruct.simplerenamed.simple1) throw new Exception("renameTest Global 4 failed");
|
||||
if (renameTest5(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest Global 5 failed");
|
||||
if (renameTest6(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest Global 6 failed");
|
||||
if (renameTest7(NewNameStruct.singlenamerenamed.singlename1) != NewNameStruct.singlenamerenamed.singlename1) throw new Exception("renameTest Global 7 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TreesClass();
|
||||
auto pine = TreesClass.trees.pine;
|
||||
|
||||
if (t.treesTest1(pine) != pine) throw new Exception("treesTest 1 failed");
|
||||
if (t.treesTest2(pine) != pine) throw new Exception("treesTest 2 failed");
|
||||
if (t.treesTest3(pine) != pine) throw new Exception("treesTest 3 failed");
|
||||
if (t.treesTest4(pine) != pine) throw new Exception("treesTest 4 failed");
|
||||
if (t.treesTest5(pine) != pine) throw new Exception("treesTest 5 failed");
|
||||
if (t.treesTest6(pine) != pine) throw new Exception("treesTest 6 failed");
|
||||
if (t.treesTest7(pine) != pine) throw new Exception("treesTest 7 failed");
|
||||
if (t.treesTest8(pine) != pine) throw new Exception("treesTest 8 failed");
|
||||
if (t.treesTest9(pine) != pine) throw new Exception("treesTest 9 failed");
|
||||
if (t.treesTestA(pine) != pine) throw new Exception("treesTest A failed");
|
||||
if (t.treesTestB(pine) != pine) throw new Exception("treesTest B failed");
|
||||
if (t.treesTestC(pine) != pine) throw new Exception("treesTest C failed");
|
||||
if (t.treesTestD(pine) != pine) throw new Exception("treesTest D failed");
|
||||
if (t.treesTestE(pine) != pine) throw new Exception("treesTest E failed");
|
||||
if (t.treesTestF(pine) != pine) throw new Exception("treesTest F failed");
|
||||
if (t.treesTestG(pine) != pine) throw new Exception("treesTest G failed");
|
||||
if (t.treesTestH(pine) != pine) throw new Exception("treesTest H failed");
|
||||
if (t.treesTestI(pine) != pine) throw new Exception("treesTest I failed");
|
||||
if (t.treesTestJ(pine) != pine) throw new Exception("treesTest J failed");
|
||||
if (t.treesTestK(pine) != pine) throw new Exception("treesTest K failed");
|
||||
if (t.treesTestL(pine) != pine) throw new Exception("treesTest L failed");
|
||||
if (t.treesTestM(pine) != pine) throw new Exception("treesTest M failed");
|
||||
if (t.treesTestN(pine) != pine) throw new Exception("treesTest N failed");
|
||||
if (t.treesTestO(pine) != pine) throw new Exception("treesTest O failed");
|
||||
|
||||
if (treesTest1(pine) != pine) throw new Exception("treesTest Global 1 failed");
|
||||
if (treesTest2(pine) != pine) throw new Exception("treesTest Global 2 failed");
|
||||
if (treesTest3(pine) != pine) throw new Exception("treesTest Global 3 failed");
|
||||
if (treesTest4(pine) != pine) throw new Exception("treesTest Global 4 failed");
|
||||
if (treesTest5(pine) != pine) throw new Exception("treesTest Global 5 failed");
|
||||
if (treesTest6(pine) != pine) throw new Exception("treesTest Global 6 failed");
|
||||
if (treesTest7(pine) != pine) throw new Exception("treesTest Global 7 failed");
|
||||
if (treesTest8(pine) != pine) throw new Exception("treesTest Global 8 failed");
|
||||
if (treesTest9(pine) != pine) throw new Exception("treesTest Global 9 failed");
|
||||
if (treesTestA(pine) != pine) throw new Exception("treesTest Global A failed");
|
||||
if (treesTestB(pine) != pine) throw new Exception("treesTest Global B failed");
|
||||
if (treesTestC(pine) != pine) throw new Exception("treesTest Global C failed");
|
||||
if (treesTestD(pine) != pine) throw new Exception("treesTest Global D failed");
|
||||
if (treesTestE(pine) != pine) throw new Exception("treesTest Global E failed");
|
||||
if (treesTestF(pine) != pine) throw new Exception("treesTest Global F failed");
|
||||
if (treesTestG(pine) != pine) throw new Exception("treesTest Global G failed");
|
||||
if (treesTestH(pine) != pine) throw new Exception("treesTest Global H failed");
|
||||
if (treesTestI(pine) != pine) throw new Exception("treesTest Global I failed");
|
||||
if (treesTestJ(pine) != pine) throw new Exception("treesTest Global J failed");
|
||||
if (treesTestK(pine) != pine) throw new Exception("treesTest Global K failed");
|
||||
if (treesTestL(pine) != pine) throw new Exception("treesTest Global L failed");
|
||||
if (treesTestM(pine) != pine) throw new Exception("treesTest Global M failed");
|
||||
// if (treesTestN(pine) != pine) throw new Exception("treesTest Global N failed");
|
||||
if (treesTestO(pine) != pine) throw new Exception("treesTest Global O failed");
|
||||
if (treesTestP(pine) != pine) throw new Exception("treesTest Global P failed");
|
||||
if (treesTestQ(pine) != pine) throw new Exception("treesTest Global Q failed");
|
||||
if (treesTestR(pine) != pine) throw new Exception("treesTest Global R failed");
|
||||
}
|
||||
{
|
||||
auto h = new HairStruct();
|
||||
auto ginger = HairStruct.hair.ginger;
|
||||
|
||||
if (h.hairTest1(ginger) != ginger) throw new Exception("hairTest 1 failed");
|
||||
if (h.hairTest2(ginger) != ginger) throw new Exception("hairTest 2 failed");
|
||||
if (h.hairTest3(ginger) != ginger) throw new Exception("hairTest 3 failed");
|
||||
if (h.hairTest4(ginger) != ginger) throw new Exception("hairTest 4 failed");
|
||||
if (h.hairTest5(ginger) != ginger) throw new Exception("hairTest 5 failed");
|
||||
if (h.hairTest6(ginger) != ginger) throw new Exception("hairTest 6 failed");
|
||||
if (h.hairTest7(ginger) != ginger) throw new Exception("hairTest 7 failed");
|
||||
if (h.hairTest8(ginger) != ginger) throw new Exception("hairTest 8 failed");
|
||||
if (h.hairTest9(ginger) != ginger) throw new Exception("hairTest 9 failed");
|
||||
if (h.hairTestA(ginger) != ginger) throw new Exception("hairTest A failed");
|
||||
if (h.hairTestB(ginger) != ginger) throw new Exception("hairTest B failed");
|
||||
|
||||
auto red = colour.red;
|
||||
if (h.colourTest1(red) != red) throw new Exception("colourTest HairStruct 1 failed");
|
||||
if (h.colourTest2(red) != red) throw new Exception("colourTest HairStruct 2 failed");
|
||||
if (h.namedanonTest1(namedanon.NamedAnon2) != namedanon.NamedAnon2) throw new Exception("namedanonTest HairStruct 1 failed");
|
||||
if (h.namedanonspaceTest1(namedanonspace.NamedAnonSpace2) != namedanonspace.NamedAnonSpace2) throw new Exception("namedanonspaceTest HairStruct 1 failed");
|
||||
|
||||
auto fir = TreesClass.trees.fir;
|
||||
if (h.treesGlobalTest1(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 1 failed");
|
||||
if (h.treesGlobalTest2(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 2 failed");
|
||||
if (h.treesGlobalTest3(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 3 failed");
|
||||
if (h.treesGlobalTest4(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 4 failed");
|
||||
}
|
||||
{
|
||||
auto blonde = HairStruct.hair.blonde;
|
||||
if (hairTest1(blonde) != blonde) throw new Exception("hairTest Global 1 failed");
|
||||
if (hairTest2(blonde) != blonde) throw new Exception("hairTest Global 2 failed");
|
||||
if (hairTest3(blonde) != blonde) throw new Exception("hairTest Global 3 failed");
|
||||
if (hairTest4(blonde) != blonde) throw new Exception("hairTest Global 4 failed");
|
||||
if (hairTest5(blonde) != blonde) throw new Exception("hairTest Global 5 failed");
|
||||
if (hairTest6(blonde) != blonde) throw new Exception("hairTest Global 6 failed");
|
||||
if (hairTest7(blonde) != blonde) throw new Exception("hairTest Global 7 failed");
|
||||
if (hairTest8(blonde) != blonde) throw new Exception("hairTest Global 8 failed");
|
||||
if (hairTest9(blonde) != blonde) throw new Exception("hairTest Global 9 failed");
|
||||
if (hairTestA(blonde) != blonde) throw new Exception("hairTest Global A failed");
|
||||
if (hairTestB(blonde) != blonde) throw new Exception("hairTest Global B failed");
|
||||
if (hairTestC(blonde) != blonde) throw new Exception("hairTest Global C failed");
|
||||
|
||||
if (hairTestA1(blonde) != blonde) throw new Exception("hairTest Global A1 failed");
|
||||
if (hairTestA2(blonde) != blonde) throw new Exception("hairTest Global A2 failed");
|
||||
if (hairTestA3(blonde) != blonde) throw new Exception("hairTest Global A3 failed");
|
||||
if (hairTestA4(blonde) != blonde) throw new Exception("hairTest Global A4 failed");
|
||||
if (hairTestA5(blonde) != blonde) throw new Exception("hairTest Global A5 failed");
|
||||
if (hairTestA6(blonde) != blonde) throw new Exception("hairTest Global A6 failed");
|
||||
if (hairTestA7(blonde) != blonde) throw new Exception("hairTest Global A7 failed");
|
||||
if (hairTestA8(blonde) != blonde) throw new Exception("hairTest Global A8 failed");
|
||||
if (hairTestA9(blonde) != blonde) throw new Exception("hairTest Global A9 failed");
|
||||
if (hairTestAA(blonde) != blonde) throw new Exception("hairTest Global AA failed");
|
||||
if (hairTestAB(blonde) != blonde) throw new Exception("hairTest Global AB failed");
|
||||
if (hairTestAC(blonde) != blonde) throw new Exception("hairTest Global AC failed");
|
||||
|
||||
if (hairTestB1(blonde) != blonde) throw new Exception("hairTest Global B1 failed");
|
||||
if (hairTestB2(blonde) != blonde) throw new Exception("hairTest Global B2 failed");
|
||||
if (hairTestB3(blonde) != blonde) throw new Exception("hairTest Global B3 failed");
|
||||
if (hairTestB4(blonde) != blonde) throw new Exception("hairTest Global B4 failed");
|
||||
if (hairTestB5(blonde) != blonde) throw new Exception("hairTest Global B5 failed");
|
||||
if (hairTestB6(blonde) != blonde) throw new Exception("hairTest Global B6 failed");
|
||||
if (hairTestB7(blonde) != blonde) throw new Exception("hairTest Global B7 failed");
|
||||
if (hairTestB8(blonde) != blonde) throw new Exception("hairTest Global B8 failed");
|
||||
if (hairTestB9(blonde) != blonde) throw new Exception("hairTest Global B9 failed");
|
||||
if (hairTestBA(blonde) != blonde) throw new Exception("hairTest Global BA failed");
|
||||
if (hairTestBB(blonde) != blonde) throw new Exception("hairTest Global BB failed");
|
||||
if (hairTestBC(blonde) != blonde) throw new Exception("hairTest Global BC failed");
|
||||
|
||||
if (hairTestC1(blonde) != blonde) throw new Exception("hairTest Global C1 failed");
|
||||
if (hairTestC2(blonde) != blonde) throw new Exception("hairTest Global C2 failed");
|
||||
if (hairTestC3(blonde) != blonde) throw new Exception("hairTest Global C3 failed");
|
||||
if (hairTestC4(blonde) != blonde) throw new Exception("hairTest Global C4 failed");
|
||||
if (hairTestC5(blonde) != blonde) throw new Exception("hairTest Global C5 failed");
|
||||
if (hairTestC6(blonde) != blonde) throw new Exception("hairTest Global C6 failed");
|
||||
if (hairTestC7(blonde) != blonde) throw new Exception("hairTest Global C7 failed");
|
||||
if (hairTestC8(blonde) != blonde) throw new Exception("hairTest Global C8 failed");
|
||||
if (hairTestC9(blonde) != blonde) throw new Exception("hairTest Global C9 failed");
|
||||
if (hairTestCA(blonde) != blonde) throw new Exception("hairTest Global CA failed");
|
||||
if (hairTestCB(blonde) != blonde) throw new Exception("hairTest Global CB failed");
|
||||
if (hairTestCC(blonde) != blonde) throw new Exception("hairTest Global CC failed");
|
||||
}
|
||||
{
|
||||
auto f = new FirStruct();
|
||||
auto blonde = HairStruct.hair.blonde;
|
||||
|
||||
if (f.hairTestFir1(blonde) != blonde) throw new Exception("hairTestFir 1 failed");
|
||||
if (f.hairTestFir2(blonde) != blonde) throw new Exception("hairTestFir 2 failed");
|
||||
if (f.hairTestFir3(blonde) != blonde) throw new Exception("hairTestFir 3 failed");
|
||||
if (f.hairTestFir4(blonde) != blonde) throw new Exception("hairTestFir 4 failed");
|
||||
if (f.hairTestFir5(blonde) != blonde) throw new Exception("hairTestFir 5 failed");
|
||||
if (f.hairTestFir6(blonde) != blonde) throw new Exception("hairTestFir 6 failed");
|
||||
if (f.hairTestFir7(blonde) != blonde) throw new Exception("hairTestFir 7 failed");
|
||||
if (f.hairTestFir8(blonde) != blonde) throw new Exception("hairTestFir 8 failed");
|
||||
if (f.hairTestFir9(blonde) != blonde) throw new Exception("hairTestFir 9 failed");
|
||||
if (f.hairTestFirA(blonde) != blonde) throw new Exception("hairTestFir A failed");
|
||||
}
|
||||
{
|
||||
GlobalInstance = globalinstance2;
|
||||
if (GlobalInstance != globalinstance2) throw new Exception("GlobalInstance 1 failed");
|
||||
|
||||
auto i = new Instances();
|
||||
i.MemberInstance = Instances.memberinstance3;
|
||||
if (i.MemberInstance != Instances.memberinstance3) throw new Exception("MemberInstance 1 failed");
|
||||
}
|
||||
// ignore enum item tests start
|
||||
{
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_zero) != 0) throw new Exception("ignoreATest 0 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_three) != 3) throw new Exception("ignoreATest 3 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_ten) != 10) throw new Exception("ignoreATest 10 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_eleven) != 11) throw new Exception("ignoreATest 11 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirteen) != 13) throw new Exception("ignoreATest 13 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_fourteen) != 14) throw new Exception("ignoreATest 14 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_twenty) != 20) throw new Exception("ignoreATest 20 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty) != 30) throw new Exception("ignoreATest 30 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_two) != 32) throw new Exception("ignoreATest 32 failed");
|
||||
if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_three) != 33) throw new Exception("ignoreATest 33 failed");
|
||||
}
|
||||
{
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_eleven) != 11) throw new Exception("ignoreBTest 11 failed");
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_twelve) != 12) throw new Exception("ignoreBTest 12 failed");
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_one) != 31) throw new Exception("ignoreBTest 31 failed");
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_two) != 32) throw new Exception("ignoreBTest 32 failed");
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_one) != 41) throw new Exception("ignoreBTest 41 failed");
|
||||
if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_two) != 42) throw new Exception("ignoreBTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_ten) != 10) throw new Exception("ignoreCTest 10 failed");
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_twelve) != 12) throw new Exception("ignoreCTest 12 failed");
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty) != 30) throw new Exception("ignoreCTest 30 failed");
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty_two) != 32) throw new Exception("ignoreCTest 32 failed");
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty) != 40) throw new Exception("ignoreCTest 40 failed");
|
||||
if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty_two) != 42) throw new Exception("ignoreCTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_one) != 21) throw new Exception("ignoreDTest 21 failed");
|
||||
if (cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_two) != 22) throw new Exception("ignoreDTest 22 failed");
|
||||
}
|
||||
{
|
||||
if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_zero) != 0) throw new Exception("ignoreETest 0 failed");
|
||||
if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_one) != 21) throw new Exception("ignoreETest 21 failed");
|
||||
if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_two) != 22) throw new Exception("ignoreETest 22 failed");
|
||||
}
|
||||
// ignore enum item tests end
|
||||
{
|
||||
if (cast(int)repeatTest(repeat.one) != 1) throw new Exception("repeatTest 1 failed");
|
||||
if (cast(int)repeatTest(repeat.initial) != 1) throw new Exception("repeatTest 2 failed");
|
||||
if (cast(int)repeatTest(repeat.two) != 2) throw new Exception("repeatTest 3 failed");
|
||||
if (cast(int)repeatTest(repeat.three) != 3) throw new Exception("repeatTest 4 failed");
|
||||
if (cast(int)repeatTest(repeat.llast) != 3) throw new Exception("repeatTest 5 failed");
|
||||
if (cast(int)repeatTest(repeat.end) != 3) throw new Exception("repeatTest 6 failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,425 @@
|
|||
module enum_thorough_runme;
|
||||
|
||||
import std.exception;
|
||||
import enum_thorough.enum_thorough;
|
||||
import enum_thorough.AnonStruct;
|
||||
import enum_thorough.colour;
|
||||
import enum_thorough.FirStruct;
|
||||
import enum_thorough.HairStruct;
|
||||
import enum_thorough.IgnoreTest;
|
||||
import enum_thorough.Instances;
|
||||
import enum_thorough.namedanon;
|
||||
import enum_thorough.namedanonspace;
|
||||
import enum_thorough.newname;
|
||||
import enum_thorough.NewNameStruct;
|
||||
import enum_thorough.repeat;
|
||||
import enum_thorough.SpeedClass;
|
||||
import enum_thorough.TClassInt;
|
||||
import enum_thorough.TemplateClassInt;
|
||||
import enum_thorough.TreesClass;
|
||||
import enum_thorough.twonames;
|
||||
import enum_thorough.TwoNamesStruct;
|
||||
|
||||
void main() {
|
||||
{
|
||||
// Anonymous enums
|
||||
int i = AnonEnum1;
|
||||
enforce(ReallyAnInteger == 200, "Test Anon 1 failed");
|
||||
i += AnonSpaceEnum1;
|
||||
i += AnonStruct.AnonStructEnum1;
|
||||
}
|
||||
{
|
||||
auto red = colour.red;
|
||||
colourTest1(red);
|
||||
colourTest2(red);
|
||||
colourTest3(red);
|
||||
colourTest4(red);
|
||||
myColour = red;
|
||||
}
|
||||
{
|
||||
auto s = new SpeedClass();
|
||||
auto speed = SpeedClass.speed.slow;
|
||||
enforce(s.speedTest1(speed) == speed, "speedTest 1 failed");
|
||||
enforce(s.speedTest2(speed) == speed, "speedTest 2 failed");
|
||||
enforce(s.speedTest3(speed) == speed, "speedTest 3 failed");
|
||||
enforce(s.speedTest4(speed) == speed, "speedTest 4 failed");
|
||||
enforce(s.speedTest5(speed) == speed, "speedTest 5 failed");
|
||||
enforce(s.speedTest6(speed) == speed, "speedTest 6 failed");
|
||||
enforce(s.speedTest7(speed) == speed, "speedTest 7 failed");
|
||||
enforce(s.speedTest8(speed) == speed, "speedTest 8 failed");
|
||||
|
||||
enforce(speedTest1(speed) == speed, "speedTest Global 1 failed");
|
||||
enforce(speedTest2(speed) == speed, "speedTest Global 2 failed");
|
||||
enforce(speedTest3(speed) == speed, "speedTest Global 3 failed");
|
||||
enforce(speedTest4(speed) == speed, "speedTest Global 4 failed");
|
||||
enforce(speedTest5(speed) == speed, "speedTest Global 5 failed");
|
||||
}
|
||||
{
|
||||
auto s = new SpeedClass();
|
||||
auto slow = SpeedClass.speed.slow;
|
||||
auto lightning = SpeedClass.speed.lightning;
|
||||
|
||||
enforce(s.mySpeedtd1 == slow, "mySpeedtd1 1 failed");
|
||||
enforce(cast(int)s.mySpeedtd1 == 10, "mySpeedtd1 2 failed");
|
||||
|
||||
s.mySpeedtd1 = lightning;
|
||||
enforce(s.mySpeedtd1 == lightning, "mySpeedtd1 3 failed");
|
||||
enforce(cast(int)s.mySpeedtd1 == 31, "mySpeedtd1 4 failed");
|
||||
}
|
||||
{
|
||||
enforce(namedanonTest1(namedanon.NamedAnon2) == namedanon.NamedAnon2, "namedanonTest 1 failed");
|
||||
}
|
||||
{
|
||||
auto val = twonames.TwoNames2;
|
||||
enforce(twonamesTest1(val) == val, "twonamesTest 1 failed");
|
||||
enforce(twonamesTest2(val) == val, "twonamesTest 2 failed");
|
||||
enforce(twonamesTest3(val) == val, "twonamesTest 3 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TwoNamesStruct();
|
||||
auto val = TwoNamesStruct.twonames.TwoNamesStruct1;
|
||||
enforce(t.twonamesTest1(val) == val, "twonamesTest 1 failed");
|
||||
enforce(t.twonamesTest2(val) == val, "twonamesTest 2 failed");
|
||||
enforce(t.twonamesTest3(val) == val, "twonamesTest 3 failed");
|
||||
}
|
||||
{
|
||||
auto val = namedanonspace.NamedAnonSpace2;
|
||||
enforce(namedanonspaceTest1(val) == val, "namedanonspaceTest 1 failed");
|
||||
enforce(namedanonspaceTest2(val) == val, "namedanonspaceTest 2 failed");
|
||||
enforce(namedanonspaceTest3(val) == val, "namedanonspaceTest 3 failed");
|
||||
enforce(namedanonspaceTest4(val) == val, "namedanonspaceTest 4 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TemplateClassInt();
|
||||
auto galileo = TemplateClassInt.scientists.galileo;
|
||||
enforce(t.scientistsTest1(galileo) == galileo, "scientistsTest 1 failed");
|
||||
enforce(t.scientistsTest2(galileo) == galileo, "scientistsTest 2 failed");
|
||||
enforce(t.scientistsTest3(galileo) == galileo, "scientistsTest 3 failed");
|
||||
enforce(t.scientistsTest4(galileo) == galileo, "scientistsTest 4 failed");
|
||||
enforce(t.scientistsTest5(galileo) == galileo, "scientistsTest 5 failed");
|
||||
enforce(t.scientistsTest6(galileo) == galileo, "scientistsTest 6 failed");
|
||||
enforce(t.scientistsTest7(galileo) == galileo, "scientistsTest 7 failed");
|
||||
enforce(t.scientistsTest8(galileo) == galileo, "scientistsTest 8 failed");
|
||||
enforce(t.scientistsTest9(galileo) == galileo, "scientistsTest 9 failed");
|
||||
// enforce(t.scientistsTestA(galileo) == galileo, "scientistsTest A failed");
|
||||
enforce(t.scientistsTestB(galileo) == galileo, "scientistsTest B failed");
|
||||
// enforce(t.scientistsTestC(galileo) == galileo, "scientistsTest C failed");
|
||||
enforce(t.scientistsTestD(galileo) == galileo, "scientistsTest D failed");
|
||||
enforce(t.scientistsTestE(galileo) == galileo, "scientistsTest E failed");
|
||||
enforce(t.scientistsTestF(galileo) == galileo, "scientistsTest F failed");
|
||||
enforce(t.scientistsTestG(galileo) == galileo, "scientistsTest G failed");
|
||||
enforce(t.scientistsTestH(galileo) == galileo, "scientistsTest H failed");
|
||||
enforce(t.scientistsTestI(galileo) == galileo, "scientistsTest I failed");
|
||||
enforce(t.scientistsTestJ(galileo) == galileo, "scientistsTest J failed");
|
||||
|
||||
enforce(scientistsTest1(galileo) == galileo, "scientistsTest Global 1 failed");
|
||||
enforce(scientistsTest2(galileo) == galileo, "scientistsTest Global 2 failed");
|
||||
enforce(scientistsTest3(galileo) == galileo, "scientistsTest Global 3 failed");
|
||||
enforce(scientistsTest4(galileo) == galileo, "scientistsTest Global 4 failed");
|
||||
enforce(scientistsTest5(galileo) == galileo, "scientistsTest Global 5 failed");
|
||||
enforce(scientistsTest6(galileo) == galileo, "scientistsTest Global 6 failed");
|
||||
enforce(scientistsTest7(galileo) == galileo, "scientistsTest Global 7 failed");
|
||||
enforce(scientistsTest8(galileo) == galileo, "scientistsTest Global 8 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TClassInt();
|
||||
auto bell = TClassInt.scientists.bell;
|
||||
auto galileo = TemplateClassInt.scientists.galileo;
|
||||
enforce(t.scientistsNameTest1(bell) == bell, "scientistsNameTest 1 failed");
|
||||
enforce(t.scientistsNameTest2(bell) == bell, "scientistsNameTest 2 failed");
|
||||
enforce(t.scientistsNameTest3(bell) == bell, "scientistsNameTest 3 failed");
|
||||
enforce(t.scientistsNameTest4(bell) == bell, "scientistsNameTest 4 failed");
|
||||
enforce(t.scientistsNameTest5(bell) == bell, "scientistsNameTest 5 failed");
|
||||
enforce(t.scientistsNameTest6(bell) == bell, "scientistsNameTest 6 failed");
|
||||
enforce(t.scientistsNameTest7(bell) == bell, "scientistsNameTest 7 failed");
|
||||
enforce(t.scientistsNameTest8(bell) == bell, "scientistsNameTest 8 failed");
|
||||
enforce(t.scientistsNameTest9(bell) == bell, "scientistsNameTest 9 failed");
|
||||
// enforce(t.scientistsNameTestA(bell) == bell, "scientistsNameTest A failed");
|
||||
enforce(t.scientistsNameTestB(bell) == bell, "scientistsNameTest B failed");
|
||||
// enforce(t.scientistsNameTestC(bell) == bell, "scientistsNameTest C failed");
|
||||
enforce(t.scientistsNameTestD(bell) == bell, "scientistsNameTest D failed");
|
||||
enforce(t.scientistsNameTestE(bell) == bell, "scientistsNameTest E failed");
|
||||
enforce(t.scientistsNameTestF(bell) == bell, "scientistsNameTest F failed");
|
||||
enforce(t.scientistsNameTestG(bell) == bell, "scientistsNameTest G failed");
|
||||
enforce(t.scientistsNameTestH(bell) == bell, "scientistsNameTest H failed");
|
||||
enforce(t.scientistsNameTestI(bell) == bell, "scientistsNameTest I failed");
|
||||
|
||||
enforce(t.scientistsNameSpaceTest1(bell) == bell, "scientistsNameSpaceTest 1 failed");
|
||||
enforce(t.scientistsNameSpaceTest2(bell) == bell, "scientistsNameSpaceTest 2 failed");
|
||||
enforce(t.scientistsNameSpaceTest3(bell) == bell, "scientistsNameSpaceTest 3 failed");
|
||||
enforce(t.scientistsNameSpaceTest4(bell) == bell, "scientistsNameSpaceTest 4 failed");
|
||||
enforce(t.scientistsNameSpaceTest5(bell) == bell, "scientistsNameSpaceTest 5 failed");
|
||||
enforce(t.scientistsNameSpaceTest6(bell) == bell, "scientistsNameSpaceTest 6 failed");
|
||||
enforce(t.scientistsNameSpaceTest7(bell) == bell, "scientistsNameSpaceTest 7 failed");
|
||||
|
||||
enforce(t.scientistsOtherTest1(galileo) == galileo, "scientistsOtherTest 1 failed");
|
||||
enforce(t.scientistsOtherTest2(galileo) == galileo, "scientistsOtherTest 2 failed");
|
||||
enforce(t.scientistsOtherTest3(galileo) == galileo, "scientistsOtherTest 3 failed");
|
||||
enforce(t.scientistsOtherTest4(galileo) == galileo, "scientistsOtherTest 4 failed");
|
||||
enforce(t.scientistsOtherTest5(galileo) == galileo, "scientistsOtherTest 5 failed");
|
||||
enforce(t.scientistsOtherTest6(galileo) == galileo, "scientistsOtherTest 6 failed");
|
||||
enforce(t.scientistsOtherTest7(galileo) == galileo, "scientistsOtherTest 7 failed");
|
||||
|
||||
enforce(scientistsNameTest1(bell) == bell, "scientistsNameTest Global 1 failed");
|
||||
enforce(scientistsNameTest2(bell) == bell, "scientistsNameTest Global 2 failed");
|
||||
enforce(scientistsNameTest3(bell) == bell, "scientistsNameTest Global 3 failed");
|
||||
enforce(scientistsNameTest4(bell) == bell, "scientistsNameTest Global 4 failed");
|
||||
enforce(scientistsNameTest5(bell) == bell, "scientistsNameTest Global 5 failed");
|
||||
enforce(scientistsNameTest6(bell) == bell, "scientistsNameTest Global 6 failed");
|
||||
enforce(scientistsNameTest7(bell) == bell, "scientistsNameTest Global 7 failed");
|
||||
|
||||
enforce(scientistsNameSpaceTest1(bell) == bell, "scientistsNameSpaceTest Global 1 failed");
|
||||
enforce(scientistsNameSpaceTest2(bell) == bell, "scientistsNameSpaceTest Global 2 failed");
|
||||
enforce(scientistsNameSpaceTest3(bell) == bell, "scientistsNameSpaceTest Global 3 failed");
|
||||
enforce(scientistsNameSpaceTest4(bell) == bell, "scientistsNameSpaceTest Global 4 failed");
|
||||
enforce(scientistsNameSpaceTest5(bell) == bell, "scientistsNameSpaceTest Global 5 failed");
|
||||
enforce(scientistsNameSpaceTest6(bell) == bell, "scientistsNameSpaceTest Global 6 failed");
|
||||
enforce(scientistsNameSpaceTest7(bell) == bell, "scientistsNameSpaceTest Global 7 failed");
|
||||
|
||||
enforce(scientistsNameSpaceTest8(bell) == bell, "scientistsNameSpaceTest Global 8 failed");
|
||||
enforce(scientistsNameSpaceTest9(bell) == bell, "scientistsNameSpaceTest Global 9 failed");
|
||||
enforce(scientistsNameSpaceTestA(bell) == bell, "scientistsNameSpaceTest Global A failed");
|
||||
enforce(scientistsNameSpaceTestB(bell) == bell, "scientistsNameSpaceTest Global B failed");
|
||||
enforce(scientistsNameSpaceTestC(bell) == bell, "scientistsNameSpaceTest Global C failed");
|
||||
enforce(scientistsNameSpaceTestD(bell) == bell, "scientistsNameSpaceTest Global D failed");
|
||||
enforce(scientistsNameSpaceTestE(bell) == bell, "scientistsNameSpaceTest Global E failed");
|
||||
|
||||
enforce(scientistsNameSpaceTestF(bell) == bell, "scientistsNameSpaceTest Global F failed");
|
||||
enforce(scientistsNameSpaceTestG(bell) == bell, "scientistsNameSpaceTest Global G failed");
|
||||
enforce(scientistsNameSpaceTestH(bell) == bell, "scientistsNameSpaceTest Global H failed");
|
||||
enforce(scientistsNameSpaceTestI(bell) == bell, "scientistsNameSpaceTest Global I failed");
|
||||
enforce(scientistsNameSpaceTestJ(bell) == bell, "scientistsNameSpaceTest Global J failed");
|
||||
enforce(scientistsNameSpaceTestK(bell) == bell, "scientistsNameSpaceTest Global K failed");
|
||||
enforce(scientistsNameSpaceTestL(bell) == bell, "scientistsNameSpaceTest Global L failed");
|
||||
}
|
||||
{
|
||||
auto val = newname.argh;
|
||||
enforce(renameTest1(val) == val, "renameTest Global 1 failed");
|
||||
enforce(renameTest2(val) == val, "renameTest Global 2 failed");
|
||||
}
|
||||
{
|
||||
auto n = new NewNameStruct();
|
||||
enforce(n.renameTest1(NewNameStruct.enumeration.bang) == NewNameStruct.enumeration.bang, "renameTest 1 failed");
|
||||
enforce(n.renameTest2(NewNameStruct.enumeration.bang) == NewNameStruct.enumeration.bang, "renameTest 2 failed");
|
||||
enforce(n.renameTest3(NewNameStruct.simplerenamed.simple1) == NewNameStruct.simplerenamed.simple1, "renameTest 3 failed");
|
||||
enforce(n.renameTest4(NewNameStruct.doublenamerenamed.doublename1) == NewNameStruct.doublenamerenamed.doublename1, "renameTest 4 failed");
|
||||
enforce(n.renameTest5(NewNameStruct.doublenamerenamed.doublename1) == NewNameStruct.doublenamerenamed.doublename1, "renameTest 5 failed");
|
||||
enforce(n.renameTest6(NewNameStruct.singlenamerenamed.singlename1) == NewNameStruct.singlenamerenamed.singlename1, "renameTest 6 failed");
|
||||
}
|
||||
{
|
||||
enforce(renameTest3(NewNameStruct.enumeration.bang) == NewNameStruct.enumeration.bang, "renameTest Global 3 failed");
|
||||
enforce(renameTest4(NewNameStruct.simplerenamed.simple1) == NewNameStruct.simplerenamed.simple1, "renameTest Global 4 failed");
|
||||
enforce(renameTest5(NewNameStruct.doublenamerenamed.doublename1) == NewNameStruct.doublenamerenamed.doublename1, "renameTest Global 5 failed");
|
||||
enforce(renameTest6(NewNameStruct.doublenamerenamed.doublename1) == NewNameStruct.doublenamerenamed.doublename1, "renameTest Global 6 failed");
|
||||
enforce(renameTest7(NewNameStruct.singlenamerenamed.singlename1) == NewNameStruct.singlenamerenamed.singlename1, "renameTest Global 7 failed");
|
||||
}
|
||||
{
|
||||
auto t = new TreesClass();
|
||||
auto pine = TreesClass.trees.pine;
|
||||
|
||||
enforce(t.treesTest1(pine) == pine, "treesTest 1 failed");
|
||||
enforce(t.treesTest2(pine) == pine, "treesTest 2 failed");
|
||||
enforce(t.treesTest3(pine) == pine, "treesTest 3 failed");
|
||||
enforce(t.treesTest4(pine) == pine, "treesTest 4 failed");
|
||||
enforce(t.treesTest5(pine) == pine, "treesTest 5 failed");
|
||||
enforce(t.treesTest6(pine) == pine, "treesTest 6 failed");
|
||||
enforce(t.treesTest7(pine) == pine, "treesTest 7 failed");
|
||||
enforce(t.treesTest8(pine) == pine, "treesTest 8 failed");
|
||||
enforce(t.treesTest9(pine) == pine, "treesTest 9 failed");
|
||||
enforce(t.treesTestA(pine) == pine, "treesTest A failed");
|
||||
enforce(t.treesTestB(pine) == pine, "treesTest B failed");
|
||||
enforce(t.treesTestC(pine) == pine, "treesTest C failed");
|
||||
enforce(t.treesTestD(pine) == pine, "treesTest D failed");
|
||||
enforce(t.treesTestE(pine) == pine, "treesTest E failed");
|
||||
enforce(t.treesTestF(pine) == pine, "treesTest F failed");
|
||||
enforce(t.treesTestG(pine) == pine, "treesTest G failed");
|
||||
enforce(t.treesTestH(pine) == pine, "treesTest H failed");
|
||||
enforce(t.treesTestI(pine) == pine, "treesTest I failed");
|
||||
enforce(t.treesTestJ(pine) == pine, "treesTest J failed");
|
||||
enforce(t.treesTestK(pine) == pine, "treesTest K failed");
|
||||
enforce(t.treesTestL(pine) == pine, "treesTest L failed");
|
||||
enforce(t.treesTestM(pine) == pine, "treesTest M failed");
|
||||
enforce(t.treesTestN(pine) == pine, "treesTest N failed");
|
||||
enforce(t.treesTestO(pine) == pine, "treesTest O failed");
|
||||
|
||||
enforce(treesTest1(pine) == pine, "treesTest Global 1 failed");
|
||||
enforce(treesTest2(pine) == pine, "treesTest Global 2 failed");
|
||||
enforce(treesTest3(pine) == pine, "treesTest Global 3 failed");
|
||||
enforce(treesTest4(pine) == pine, "treesTest Global 4 failed");
|
||||
enforce(treesTest5(pine) == pine, "treesTest Global 5 failed");
|
||||
enforce(treesTest6(pine) == pine, "treesTest Global 6 failed");
|
||||
enforce(treesTest7(pine) == pine, "treesTest Global 7 failed");
|
||||
enforce(treesTest8(pine) == pine, "treesTest Global 8 failed");
|
||||
enforce(treesTest9(pine) == pine, "treesTest Global 9 failed");
|
||||
enforce(treesTestA(pine) == pine, "treesTest Global A failed");
|
||||
enforce(treesTestB(pine) == pine, "treesTest Global B failed");
|
||||
enforce(treesTestC(pine) == pine, "treesTest Global C failed");
|
||||
enforce(treesTestD(pine) == pine, "treesTest Global D failed");
|
||||
enforce(treesTestE(pine) == pine, "treesTest Global E failed");
|
||||
enforce(treesTestF(pine) == pine, "treesTest Global F failed");
|
||||
enforce(treesTestG(pine) == pine, "treesTest Global G failed");
|
||||
enforce(treesTestH(pine) == pine, "treesTest Global H failed");
|
||||
enforce(treesTestI(pine) == pine, "treesTest Global I failed");
|
||||
enforce(treesTestJ(pine) == pine, "treesTest Global J failed");
|
||||
enforce(treesTestK(pine) == pine, "treesTest Global K failed");
|
||||
enforce(treesTestL(pine) == pine, "treesTest Global L failed");
|
||||
enforce(treesTestM(pine) == pine, "treesTest Global M failed");
|
||||
// enforce(treesTestN(pine) == pine, "treesTest Global N failed");
|
||||
enforce(treesTestO(pine) == pine, "treesTest Global O failed");
|
||||
enforce(treesTestP(pine) == pine, "treesTest Global P failed");
|
||||
enforce(treesTestQ(pine) == pine, "treesTest Global Q failed");
|
||||
enforce(treesTestR(pine) == pine, "treesTest Global R failed");
|
||||
}
|
||||
{
|
||||
auto h = new HairStruct();
|
||||
auto ginger = HairStruct.hair.ginger;
|
||||
|
||||
enforce(h.hairTest1(ginger) == ginger, "hairTest 1 failed");
|
||||
enforce(h.hairTest2(ginger) == ginger, "hairTest 2 failed");
|
||||
enforce(h.hairTest3(ginger) == ginger, "hairTest 3 failed");
|
||||
enforce(h.hairTest4(ginger) == ginger, "hairTest 4 failed");
|
||||
enforce(h.hairTest5(ginger) == ginger, "hairTest 5 failed");
|
||||
enforce(h.hairTest6(ginger) == ginger, "hairTest 6 failed");
|
||||
enforce(h.hairTest7(ginger) == ginger, "hairTest 7 failed");
|
||||
enforce(h.hairTest8(ginger) == ginger, "hairTest 8 failed");
|
||||
enforce(h.hairTest9(ginger) == ginger, "hairTest 9 failed");
|
||||
enforce(h.hairTestA(ginger) == ginger, "hairTest A failed");
|
||||
enforce(h.hairTestB(ginger) == ginger, "hairTest B failed");
|
||||
|
||||
auto red = colour.red;
|
||||
enforce(h.colourTest1(red) == red, "colourTest HairStruct 1 failed");
|
||||
enforce(h.colourTest2(red) == red, "colourTest HairStruct 2 failed");
|
||||
enforce(h.namedanonTest1(namedanon.NamedAnon2) == namedanon.NamedAnon2, "namedanonTest HairStruct 1 failed");
|
||||
enforce(h.namedanonspaceTest1(namedanonspace.NamedAnonSpace2) == namedanonspace.NamedAnonSpace2, "namedanonspaceTest HairStruct 1 failed");
|
||||
|
||||
auto fir = TreesClass.trees.fir;
|
||||
enforce(h.treesGlobalTest1(fir) == fir, "treesGlobalTest1 HairStruct 1 failed");
|
||||
enforce(h.treesGlobalTest2(fir) == fir, "treesGlobalTest1 HairStruct 2 failed");
|
||||
enforce(h.treesGlobalTest3(fir) == fir, "treesGlobalTest1 HairStruct 3 failed");
|
||||
enforce(h.treesGlobalTest4(fir) == fir, "treesGlobalTest1 HairStruct 4 failed");
|
||||
}
|
||||
{
|
||||
auto blonde = HairStruct.hair.blonde;
|
||||
enforce(hairTest1(blonde) == blonde, "hairTest Global 1 failed");
|
||||
enforce(hairTest2(blonde) == blonde, "hairTest Global 2 failed");
|
||||
enforce(hairTest3(blonde) == blonde, "hairTest Global 3 failed");
|
||||
enforce(hairTest4(blonde) == blonde, "hairTest Global 4 failed");
|
||||
enforce(hairTest5(blonde) == blonde, "hairTest Global 5 failed");
|
||||
enforce(hairTest6(blonde) == blonde, "hairTest Global 6 failed");
|
||||
enforce(hairTest7(blonde) == blonde, "hairTest Global 7 failed");
|
||||
enforce(hairTest8(blonde) == blonde, "hairTest Global 8 failed");
|
||||
enforce(hairTest9(blonde) == blonde, "hairTest Global 9 failed");
|
||||
enforce(hairTestA(blonde) == blonde, "hairTest Global A failed");
|
||||
enforce(hairTestB(blonde) == blonde, "hairTest Global B failed");
|
||||
enforce(hairTestC(blonde) == blonde, "hairTest Global C failed");
|
||||
|
||||
enforce(hairTestA1(blonde) == blonde, "hairTest Global A1 failed");
|
||||
enforce(hairTestA2(blonde) == blonde, "hairTest Global A2 failed");
|
||||
enforce(hairTestA3(blonde) == blonde, "hairTest Global A3 failed");
|
||||
enforce(hairTestA4(blonde) == blonde, "hairTest Global A4 failed");
|
||||
enforce(hairTestA5(blonde) == blonde, "hairTest Global A5 failed");
|
||||
enforce(hairTestA6(blonde) == blonde, "hairTest Global A6 failed");
|
||||
enforce(hairTestA7(blonde) == blonde, "hairTest Global A7 failed");
|
||||
enforce(hairTestA8(blonde) == blonde, "hairTest Global A8 failed");
|
||||
enforce(hairTestA9(blonde) == blonde, "hairTest Global A9 failed");
|
||||
enforce(hairTestAA(blonde) == blonde, "hairTest Global AA failed");
|
||||
enforce(hairTestAB(blonde) == blonde, "hairTest Global AB failed");
|
||||
enforce(hairTestAC(blonde) == blonde, "hairTest Global AC failed");
|
||||
|
||||
enforce(hairTestB1(blonde) == blonde, "hairTest Global B1 failed");
|
||||
enforce(hairTestB2(blonde) == blonde, "hairTest Global B2 failed");
|
||||
enforce(hairTestB3(blonde) == blonde, "hairTest Global B3 failed");
|
||||
enforce(hairTestB4(blonde) == blonde, "hairTest Global B4 failed");
|
||||
enforce(hairTestB5(blonde) == blonde, "hairTest Global B5 failed");
|
||||
enforce(hairTestB6(blonde) == blonde, "hairTest Global B6 failed");
|
||||
enforce(hairTestB7(blonde) == blonde, "hairTest Global B7 failed");
|
||||
enforce(hairTestB8(blonde) == blonde, "hairTest Global B8 failed");
|
||||
enforce(hairTestB9(blonde) == blonde, "hairTest Global B9 failed");
|
||||
enforce(hairTestBA(blonde) == blonde, "hairTest Global BA failed");
|
||||
enforce(hairTestBB(blonde) == blonde, "hairTest Global BB failed");
|
||||
enforce(hairTestBC(blonde) == blonde, "hairTest Global BC failed");
|
||||
|
||||
enforce(hairTestC1(blonde) == blonde, "hairTest Global C1 failed");
|
||||
enforce(hairTestC2(blonde) == blonde, "hairTest Global C2 failed");
|
||||
enforce(hairTestC3(blonde) == blonde, "hairTest Global C3 failed");
|
||||
enforce(hairTestC4(blonde) == blonde, "hairTest Global C4 failed");
|
||||
enforce(hairTestC5(blonde) == blonde, "hairTest Global C5 failed");
|
||||
enforce(hairTestC6(blonde) == blonde, "hairTest Global C6 failed");
|
||||
enforce(hairTestC7(blonde) == blonde, "hairTest Global C7 failed");
|
||||
enforce(hairTestC8(blonde) == blonde, "hairTest Global C8 failed");
|
||||
enforce(hairTestC9(blonde) == blonde, "hairTest Global C9 failed");
|
||||
enforce(hairTestCA(blonde) == blonde, "hairTest Global CA failed");
|
||||
enforce(hairTestCB(blonde) == blonde, "hairTest Global CB failed");
|
||||
enforce(hairTestCC(blonde) == blonde, "hairTest Global CC failed");
|
||||
}
|
||||
{
|
||||
auto f = new FirStruct();
|
||||
auto blonde = HairStruct.hair.blonde;
|
||||
|
||||
enforce(f.hairTestFir1(blonde) == blonde, "hairTestFir 1 failed");
|
||||
enforce(f.hairTestFir2(blonde) == blonde, "hairTestFir 2 failed");
|
||||
enforce(f.hairTestFir3(blonde) == blonde, "hairTestFir 3 failed");
|
||||
enforce(f.hairTestFir4(blonde) == blonde, "hairTestFir 4 failed");
|
||||
enforce(f.hairTestFir5(blonde) == blonde, "hairTestFir 5 failed");
|
||||
enforce(f.hairTestFir6(blonde) == blonde, "hairTestFir 6 failed");
|
||||
enforce(f.hairTestFir7(blonde) == blonde, "hairTestFir 7 failed");
|
||||
enforce(f.hairTestFir8(blonde) == blonde, "hairTestFir 8 failed");
|
||||
enforce(f.hairTestFir9(blonde) == blonde, "hairTestFir 9 failed");
|
||||
enforce(f.hairTestFirA(blonde) == blonde, "hairTestFir A failed");
|
||||
}
|
||||
{
|
||||
GlobalInstance = globalinstance2;
|
||||
enforce(GlobalInstance == globalinstance2, "GlobalInstance 1 failed");
|
||||
|
||||
auto i = new Instances();
|
||||
i.MemberInstance = Instances.memberinstance3;
|
||||
enforce(i.MemberInstance == Instances.memberinstance3, "MemberInstance 1 failed");
|
||||
}
|
||||
// ignore enum item tests start
|
||||
{
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_zero) == 0, "ignoreATest 0 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_three) == 3, "ignoreATest 3 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_ten) == 10, "ignoreATest 10 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_eleven) == 11, "ignoreATest 11 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirteen) == 13, "ignoreATest 13 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_fourteen) == 14, "ignoreATest 14 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_twenty) == 20, "ignoreATest 20 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty) == 30, "ignoreATest 30 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_two) == 32, "ignoreATest 32 failed");
|
||||
enforce(cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_three) == 33, "ignoreATest 33 failed");
|
||||
}
|
||||
{
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_eleven) == 11, "ignoreBTest 11 failed");
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_twelve) == 12, "ignoreBTest 12 failed");
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_one) == 31, "ignoreBTest 31 failed");
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_two) == 32, "ignoreBTest 32 failed");
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_one) == 41, "ignoreBTest 41 failed");
|
||||
enforce(cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_two) == 42, "ignoreBTest 42 failed");
|
||||
}
|
||||
{
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_ten), "ignoreCTest 10 failed");
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_twelve) == 12, "ignoreCTest 12 failed");
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty) == 30, "ignoreCTest 30 failed");
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty_two) == 32, "ignoreCTest 32 failed");
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty) == 40, "ignoreCTest 40 failed");
|
||||
enforce(cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty_two) == 42, "ignoreCTest 42 failed");
|
||||
}
|
||||
{
|
||||
enforce(cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_one) == 21, "ignoreDTest 21 failed");
|
||||
enforce(cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_two) == 22, "ignoreDTest 22 failed");
|
||||
}
|
||||
{
|
||||
enforce(cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_zero) == 0, "ignoreETest 0 failed");
|
||||
enforce(cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_one) == 21, "ignoreETest 21 failed");
|
||||
enforce(cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_two) == 22, "ignoreETest 22 failed");
|
||||
}
|
||||
// ignore enum item tests end
|
||||
{
|
||||
enforce(cast(int)repeatTest(repeat.one) == 1, "repeatTest 1 failed");
|
||||
enforce(cast(int)repeatTest(repeat.initial) == 1, "repeatTest 2 failed");
|
||||
enforce(cast(int)repeatTest(repeat.two) == 2, "repeatTest 3 failed");
|
||||
enforce(cast(int)repeatTest(repeat.three) == 3, "repeatTest 4 failed");
|
||||
enforce(cast(int)repeatTest(repeat.llast) == 3, "repeatTest 5 failed");
|
||||
enforce(cast(int)repeatTest(repeat.end) == 3, "repeatTest 6 failed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
module inherit_target_language_runme;
|
||||
|
||||
import inherit_target_language.BaseX;
|
||||
import inherit_target_language.Derived1;
|
||||
import inherit_target_language.Derived2;
|
||||
import inherit_target_language.DerivedX;
|
||||
import inherit_target_language.MultipleDerived1;
|
||||
import inherit_target_language.MultipleDerived2;
|
||||
import inherit_target_language.MultipleDerived3;
|
||||
import inherit_target_language.MultipleDerived4;
|
||||
|
||||
void main() {
|
||||
(new Derived1()).targetLanguageBaseMethod();
|
||||
(new Derived2()).targetLanguageBaseMethod();
|
||||
|
||||
(new MultipleDerived1()).targetLanguageBaseMethod();
|
||||
(new MultipleDerived2()).targetLanguageBaseMethod();
|
||||
(new MultipleDerived3()).f();
|
||||
(new MultipleDerived4()).g();
|
||||
|
||||
auto baseX = new BaseX();
|
||||
baseX.basex();
|
||||
baseX.targetLanguageBase2Method();
|
||||
|
||||
auto derivedX = new DerivedX();
|
||||
derivedX.basex();
|
||||
derivedX.derivedx();
|
||||
derivedX.targetLanguageBase2Method();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
module inherit_target_language_runme;
|
||||
|
||||
import inherit_target_language.BaseX;
|
||||
import inherit_target_language.Derived1;
|
||||
import inherit_target_language.Derived2;
|
||||
import inherit_target_language.DerivedX;
|
||||
import inherit_target_language.MultipleDerived1;
|
||||
import inherit_target_language.MultipleDerived2;
|
||||
import inherit_target_language.MultipleDerived3;
|
||||
import inherit_target_language.MultipleDerived4;
|
||||
|
||||
void main() {
|
||||
(new Derived1()).targetLanguageBaseMethod();
|
||||
(new Derived2()).targetLanguageBaseMethod();
|
||||
|
||||
(new MultipleDerived1()).targetLanguageBaseMethod();
|
||||
(new MultipleDerived2()).targetLanguageBaseMethod();
|
||||
(new MultipleDerived3()).f();
|
||||
(new MultipleDerived4()).g();
|
||||
|
||||
auto baseX = new BaseX();
|
||||
baseX.basex();
|
||||
baseX.targetLanguageBase2Method();
|
||||
|
||||
auto derivedX = new DerivedX();
|
||||
derivedX.basex();
|
||||
derivedX.derivedx();
|
||||
derivedX.targetLanguageBase2Method();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
module li_attribute_runme;
|
||||
|
||||
import li_attribute.A;
|
||||
import li_attribute.B;
|
||||
import li_attribute.MyClass;
|
||||
import li_attribute.MyClassVal;
|
||||
import li_attribute.MyStringyClass;
|
||||
import li_attribute.MyFoo;
|
||||
import li_attribute.Param_i;
|
||||
|
||||
void main() {
|
||||
auto aa = new A(1,2,3);
|
||||
|
||||
if (aa.a != 1)
|
||||
throw new Exception("error");
|
||||
aa.a = 3;
|
||||
if (aa.a != 3)
|
||||
throw new Exception("error");
|
||||
|
||||
if (aa.b != 2)
|
||||
throw new Exception("error");
|
||||
aa.b = 5;
|
||||
if (aa.b != 5)
|
||||
throw new Exception("error");
|
||||
|
||||
if (aa.d != aa.b)
|
||||
throw new Exception("error");
|
||||
|
||||
if (aa.c != 3)
|
||||
throw new Exception("error");
|
||||
|
||||
auto pi = new Param_i(7);
|
||||
if (pi.value != 7)
|
||||
throw new Exception("error");
|
||||
|
||||
pi.value=3;
|
||||
if (pi.value != 3)
|
||||
throw new Exception("error");
|
||||
|
||||
auto b = new B(aa);
|
||||
if (b.a.c != 3)
|
||||
throw new Exception("error");
|
||||
|
||||
// class/struct attribute with get/set methods using return/pass by reference
|
||||
auto myFoo = new MyFoo();
|
||||
myFoo.x = 8;
|
||||
auto myClass = new MyClass();
|
||||
myClass.Foo = myFoo;
|
||||
if (myClass.Foo.x != 8)
|
||||
throw new Exception("error");
|
||||
|
||||
// class/struct attribute with get/set methods using return/pass by value
|
||||
auto myClassVal = new MyClassVal();
|
||||
if (myClassVal.ReadWriteFoo.x != -1)
|
||||
throw new Exception("error");
|
||||
if (myClassVal.ReadOnlyFoo.x != -1)
|
||||
throw new Exception("error");
|
||||
myClassVal.ReadWriteFoo = myFoo;
|
||||
if (myClassVal.ReadWriteFoo.x != 8)
|
||||
throw new Exception("error");
|
||||
if (myClassVal.ReadOnlyFoo.x != 8)
|
||||
throw new Exception("error");
|
||||
|
||||
// string attribute with get/set methods using return/pass by value
|
||||
auto myStringClass = new MyStringyClass("initial string");
|
||||
if (myStringClass.ReadWriteString != "initial string")
|
||||
throw new Exception("error");
|
||||
if (myStringClass.ReadOnlyString != "initial string")
|
||||
throw new Exception("error");
|
||||
myStringClass.ReadWriteString = "changed string";
|
||||
if (myStringClass.ReadWriteString != "changed string")
|
||||
throw new Exception("error");
|
||||
if (myStringClass.ReadOnlyString != "changed string")
|
||||
throw new Exception("error");
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
module li_attribute_runme;
|
||||
|
||||
import std.exception;
|
||||
import li_attribute.A;
|
||||
import li_attribute.B;
|
||||
import li_attribute.MyClass;
|
||||
import li_attribute.MyClassVal;
|
||||
import li_attribute.MyStringyClass;
|
||||
import li_attribute.MyFoo;
|
||||
import li_attribute.Param_i;
|
||||
|
||||
void main() {
|
||||
auto aa = new A(1,2,3);
|
||||
|
||||
enforce(aa.a == 1);
|
||||
aa.a = 3;
|
||||
enforce(aa.a == 3);
|
||||
|
||||
enforce(aa.b == 2);
|
||||
aa.b = 5;
|
||||
enforce(aa.b == 5);
|
||||
|
||||
enforce(aa.d == aa.b);
|
||||
|
||||
enforce(aa.c == 3);
|
||||
|
||||
auto pi = new Param_i(7);
|
||||
enforce(pi.value == 7);
|
||||
|
||||
pi.value=3;
|
||||
enforce(pi.value == 3);
|
||||
|
||||
auto b = new B(aa);
|
||||
enforce(b.a.c == 3);
|
||||
|
||||
// class/struct attribute with get/set methods using return/pass by reference
|
||||
auto myFoo = new MyFoo();
|
||||
myFoo.x = 8;
|
||||
auto myClass = new MyClass();
|
||||
myClass.Foo = myFoo;
|
||||
enforce(myClass.Foo.x == 8);
|
||||
|
||||
// class/struct attribute with get/set methods using return/pass by value
|
||||
auto myClassVal = new MyClassVal();
|
||||
enforce(myClassVal.ReadWriteFoo.x == -1);
|
||||
enforce(myClassVal.ReadOnlyFoo.x == -1);
|
||||
myClassVal.ReadWriteFoo = myFoo;
|
||||
enforce(myClassVal.ReadWriteFoo.x == 8);
|
||||
enforce(myClassVal.ReadOnlyFoo.x == 8);
|
||||
|
||||
// string attribute with get/set methods using return/pass by value
|
||||
auto myStringClass = new MyStringyClass("initial string");
|
||||
enforce(myStringClass.ReadWriteString == "initial string");
|
||||
enforce(myStringClass.ReadOnlyString == "initial string");
|
||||
myStringClass.ReadWriteString = "changed string";
|
||||
enforce(myStringClass.ReadWriteString == "changed string");
|
||||
enforce(myStringClass.ReadOnlyString == "changed string");
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
module li_boost_shared_ptr_runme_bits;
|
||||
|
||||
import li_boost_shared_ptr_bits.li_boost_shared_ptr_bits;
|
||||
import li_boost_shared_ptr_bits.HiddenDestructor;
|
||||
import li_boost_shared_ptr_bits.IntHolder;
|
||||
import li_boost_shared_ptr_bits.VectorIntHolder;
|
||||
|
||||
void main() {
|
||||
auto v = new VectorIntHolder();
|
||||
v ~= new IntHolder(11);
|
||||
v ~= new IntHolder(22);
|
||||
v ~= new IntHolder(33);
|
||||
|
||||
if (sum(v) != 66) {
|
||||
throw new Exception("sum is wrong");
|
||||
}
|
||||
|
||||
{
|
||||
scope hidden = HiddenDestructor.create();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
module li_boost_shared_ptr_runme_bits;
|
||||
|
||||
import std.exception;
|
||||
import li_boost_shared_ptr_bits.li_boost_shared_ptr_bits;
|
||||
import li_boost_shared_ptr_bits.HiddenDestructor;
|
||||
import li_boost_shared_ptr_bits.IntHolder;
|
||||
import li_boost_shared_ptr_bits.VectorIntHolder;
|
||||
|
||||
void main() {
|
||||
auto v = new VectorIntHolder();
|
||||
v ~= new IntHolder(11);
|
||||
v ~= new IntHolder(22);
|
||||
v ~= new IntHolder(33);
|
||||
enforce(sum(v) == 66, "sum is wrong");
|
||||
|
||||
{
|
||||
scope hidden = HiddenDestructor.create();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,604 @@
|
|||
module li_boost_shared_ptr_runme;
|
||||
|
||||
import tango.io.Stdout;
|
||||
import tango.core.Exception;
|
||||
import tango.core.Memory;
|
||||
import tango.core.Thread;
|
||||
import tango.text.convert.Integer;
|
||||
import li_boost_shared_ptr.li_boost_shared_ptr;
|
||||
import li_boost_shared_ptr.Klass;
|
||||
import li_boost_shared_ptr.KlassDerived;
|
||||
import li_boost_shared_ptr.Klass3rdDerived;
|
||||
import li_boost_shared_ptr.MemberVariables;
|
||||
import li_boost_shared_ptr.PairIntDouble;
|
||||
|
||||
// Debugging flag
|
||||
const bool TRACE = false;
|
||||
|
||||
void main() {
|
||||
if (TRACE)
|
||||
Stdout("---> STARTED <---").newline;
|
||||
|
||||
debug_shared=TRACE;
|
||||
|
||||
// Change loop count to run for a long time to monitor memory
|
||||
const int LOOP_COUNT = 1; // 50000;
|
||||
for (int i = 0; i < LOOP_COUNT; ++i) {
|
||||
runTest();
|
||||
GC.collect();
|
||||
}
|
||||
|
||||
if (TRACE)
|
||||
Stdout("---> NEARLY FINISHED <---").newline;
|
||||
|
||||
// Try to get the GC to collect everything not referenced anymore.
|
||||
int countdown = 100;
|
||||
while (--countdown) {
|
||||
GC.collect();
|
||||
if (Klass.getTotal_count() == 1)
|
||||
break;
|
||||
Thread.sleep(0.01);
|
||||
}
|
||||
|
||||
// A single remaining instance expected: the global variable (GlobalValue).
|
||||
if (Klass.getTotal_count() != 1)
|
||||
throw new Exception("Klass.total_count=" ~ toString(Klass.getTotal_count()));
|
||||
|
||||
// A single remaining instance expected: the global variable (GlobalSmartValue).
|
||||
int wrapper_count = shared_ptr_wrapper_count();
|
||||
if (wrapper_count != NOT_COUNTING)
|
||||
if (wrapper_count != 1)
|
||||
throw new Exception("shared_ptr wrapper count=" ~ toString(wrapper_count));
|
||||
|
||||
if (TRACE)
|
||||
Stdout("---> FINISHED <---").newline;
|
||||
}
|
||||
|
||||
void runTest() {
|
||||
// simple shared_ptr usage - created in C++
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
char[] val = k.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// simple shared_ptr usage - not created in C++
|
||||
{
|
||||
auto k = factorycreate();
|
||||
char[] val = k.getValue();
|
||||
verifyValue("factorycreate", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// pass by shared_ptr
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointertest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointertest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerreftest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointerreftest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointerpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by value
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = valuetest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my valuetest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = pointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my pointertest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = reftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my reftest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = pointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my pointerreftest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// null tests
|
||||
{
|
||||
Klass k = null;
|
||||
|
||||
// TODO: add in const versions too
|
||||
if (smartpointertest(k) !is null)
|
||||
throw new Exception("return was not null");
|
||||
|
||||
if (smartpointerpointertest(k) !is null)
|
||||
throw new Exception("return was not null");
|
||||
|
||||
if (smartpointerreftest(k) !is null)
|
||||
throw new Exception("return was not null");
|
||||
|
||||
if (smartpointerpointerreftest(k) !is null)
|
||||
throw new Exception("return was not null");
|
||||
|
||||
if (nullsmartpointerpointertest(null) != "null pointer")
|
||||
throw new Exception("not null smartpointer pointer");
|
||||
|
||||
try { valuetest(k); throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
|
||||
|
||||
if (pointertest(k) !is null)
|
||||
throw new Exception("return was not null");
|
||||
|
||||
try { reftest(k); throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
// $owner
|
||||
{
|
||||
auto k = pointerownertest();
|
||||
char[] val = k.getValue();
|
||||
verifyValue("pointerownertest", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
{
|
||||
auto k = smartpointerpointerownertest();
|
||||
char[] val = k.getValue();
|
||||
verifyValue("smartpointerpointerownertest", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
////////////////////////////////// Derived classes ////////////////////////////////////////
|
||||
// derived pass by shared_ptr
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrtest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrtest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrpointertest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrreftest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr pointer ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrpointerreftest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by pointer
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedpointertest-Derived", val);
|
||||
verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
// derived pass by ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my derivedreftest-Derived", val);
|
||||
verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
////////////////////////////////// Derived and base class mixed ////////////////////////////////////////
|
||||
// pass by shared_ptr (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointertest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerpointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointertest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr reference (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerreftest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer reference (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerpointerreftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointerreftest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by value (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = valuetest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my valuetest", val); // note slicing
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = pointertest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my pointertest-Derived", val);
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by ref (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = reftest(k);
|
||||
char[] val = kret.getValue();
|
||||
verifyValue("me oh my reftest-Derived", val);
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// 3rd derived class
|
||||
{
|
||||
auto k = new Klass3rdDerived("me oh my");
|
||||
char[] val = k.getValue();
|
||||
verifyValue("me oh my-3rdDerived", val);
|
||||
verifyCount(3, k); // 3 classes in inheritance chain == 3 swigCPtr values
|
||||
val = test3rdupcast(k);
|
||||
verifyValue("me oh my-3rdDerived", val);
|
||||
verifyCount(3, k);
|
||||
}
|
||||
|
||||
////////////////////////////////// Member variables ////////////////////////////////////////
|
||||
// smart pointer by value
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member value");
|
||||
m.SmartMemberValue = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("smart member value", val);
|
||||
verifyCount(2, k);
|
||||
|
||||
auto kmember = m.SmartMemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member value", val);
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
}
|
||||
// smart pointer by pointer
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member pointer");
|
||||
m.SmartMemberPointer = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("smart member pointer", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.SmartMemberPointer;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member pointer", val);
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
}
|
||||
// smart pointer by reference
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member reference");
|
||||
m.SmartMemberReference = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(2, k);
|
||||
|
||||
auto kmember = m.SmartMemberReference;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
|
||||
// The C++ reference refers to SmartMemberValue...
|
||||
auto kmemberVal = m.SmartMemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(4, kmemberVal);
|
||||
verifyCount(4, kmember);
|
||||
verifyCount(4, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
}
|
||||
// plain by value
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member value");
|
||||
m.MemberValue = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("plain member value", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member value", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
// plain by pointer
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member pointer");
|
||||
m.MemberPointer = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("plain member pointer", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberPointer;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member pointer", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
// plain by reference
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member reference");
|
||||
m.MemberReference = k;
|
||||
char[] val = k.getValue();
|
||||
verifyValue("plain member reference", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberReference;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member reference", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// null member variables
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
|
||||
// shared_ptr by value
|
||||
auto k = m.SmartMemberValue;
|
||||
if (k !is null)
|
||||
throw new Exception("expected null");
|
||||
m.SmartMemberValue = null;
|
||||
k = m.SmartMemberValue;
|
||||
if (k !is null)
|
||||
throw new Exception("expected null");
|
||||
verifyCount(0, k);
|
||||
|
||||
// plain by value
|
||||
try { m.MemberValue = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
////////////////////////////////// Global variables ////////////////////////////////////////
|
||||
// smart pointer
|
||||
{
|
||||
auto kglobal = GlobalSmartValue;
|
||||
if (kglobal !is null)
|
||||
throw new Exception("expected null");
|
||||
|
||||
auto k = new Klass("smart global value");
|
||||
GlobalSmartValue = k;
|
||||
verifyCount(2, k);
|
||||
|
||||
kglobal = GlobalSmartValue;
|
||||
char[] val = kglobal.getValue();
|
||||
verifyValue("smart global value", val);
|
||||
verifyCount(3, kglobal);
|
||||
verifyCount(3, k);
|
||||
verifyValue("smart global value", GlobalSmartValue.getValue());
|
||||
GlobalSmartValue = null;
|
||||
}
|
||||
// plain value
|
||||
{
|
||||
Klass kglobal;
|
||||
|
||||
auto k = new Klass("global value");
|
||||
GlobalValue = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalValue;
|
||||
char[] val = kglobal.getValue();
|
||||
verifyValue("global value", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
verifyValue("global value", GlobalValue.getValue());
|
||||
|
||||
try { GlobalValue = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
|
||||
}
|
||||
// plain pointer
|
||||
{
|
||||
auto kglobal = GlobalPointer;
|
||||
if (kglobal !is null)
|
||||
throw new Exception("expected null");
|
||||
|
||||
auto k = new Klass("global pointer");
|
||||
GlobalPointer = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalPointer;
|
||||
char[] val = kglobal.getValue();
|
||||
verifyValue("global pointer", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
GlobalPointer = null;
|
||||
}
|
||||
// plain reference
|
||||
{
|
||||
Klass kglobal;
|
||||
|
||||
auto k = new Klass("global reference");
|
||||
GlobalReference = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalReference;
|
||||
char[] val = kglobal.getValue();
|
||||
verifyValue("global reference", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
|
||||
try { GlobalReference = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
////////////////////////////////// Templates ////////////////////////////////////////
|
||||
{
|
||||
PairIntDouble pid = new PairIntDouble(10, 20.2);
|
||||
if (pid.baseVal1 != 20 || pid.baseVal2 != 40.4)
|
||||
throw new Exception("Base values wrong");
|
||||
if (pid.val1 != 10 || pid.val2 != 20.2)
|
||||
throw new Exception("Derived Values wrong");
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyValue(char[] expected, char[] got) {
|
||||
if (expected != got)
|
||||
throw new Exception("verify value failed. Expected: " ~ expected ~ " Got: " ~ got);
|
||||
}
|
||||
|
||||
private void verifyCount(int expected, Klass k) {
|
||||
// We deliberately call the use_count(Klass) overload also for objects which
|
||||
// are instances of a subclass of Klass (due to static dispatch); things still
|
||||
// have to work.
|
||||
int got = use_count(k);
|
||||
if (expected != got)
|
||||
throw new Exception("verify use_count failed. Expected: " ~ toString(expected) ~ " Got: " ~ toString(got));
|
||||
}
|
|
@ -0,0 +1,602 @@
|
|||
module li_boost_shared_ptr_runme;
|
||||
|
||||
import core.memory;
|
||||
import core.thread;
|
||||
import std.conv;
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
import li_boost_shared_ptr.li_boost_shared_ptr;
|
||||
import li_boost_shared_ptr.Klass;
|
||||
import li_boost_shared_ptr.KlassDerived;
|
||||
import li_boost_shared_ptr.Klass3rdDerived;
|
||||
import li_boost_shared_ptr.MemberVariables;
|
||||
import li_boost_shared_ptr.PairIntDouble;
|
||||
|
||||
// Debugging flag
|
||||
enum TRACE = false;
|
||||
|
||||
void main() {
|
||||
if (TRACE)
|
||||
writeln("---> STARTED <---");
|
||||
|
||||
debug_shared = TRACE;
|
||||
|
||||
// Change loop count to run for a long time to monitor memory
|
||||
enum LOOP_COUNT = 1; // 50000;
|
||||
for (int i = 0; i < LOOP_COUNT; ++i) {
|
||||
runTest();
|
||||
GC.collect();
|
||||
}
|
||||
|
||||
if (TRACE)
|
||||
writeln("---> NEARLY FINISHED <---");
|
||||
|
||||
// Try to get the GC to collect everything not referenced anymore.
|
||||
int countdown = 100;
|
||||
while (--countdown) {
|
||||
GC.collect();
|
||||
if (Klass.getTotal_count() == 1)
|
||||
break;
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
// A single remaining instance expected: the global variable (GlobalValue).
|
||||
if (Klass.getTotal_count() != 1)
|
||||
throw new Exception("Klass.total_count=" ~ to!string(Klass.getTotal_count()));
|
||||
|
||||
// A single remaining instance expected: the global variable (GlobalSmartValue).
|
||||
int wrapper_count = shared_ptr_wrapper_count();
|
||||
if (wrapper_count != NOT_COUNTING)
|
||||
if (wrapper_count != 1)
|
||||
throw new Exception("shared_ptr wrapper count=" ~ to!string(wrapper_count));
|
||||
|
||||
if (TRACE)
|
||||
writeln("---> FINISHED <---");
|
||||
}
|
||||
|
||||
void runTest() {
|
||||
// simple shared_ptr usage - created in C++
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
string val = k.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// simple shared_ptr usage - not created in C++
|
||||
{
|
||||
auto k = factorycreate();
|
||||
string val = k.getValue();
|
||||
verifyValue("factorycreate", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// pass by shared_ptr
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointertest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointertest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerreftest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = smartpointerpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointerreftest", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointerpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// const pass by shared_ptr reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = constsmartpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my", val);
|
||||
verifyCount(2, k);
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
// pass by value
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = valuetest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my valuetest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = pointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my pointertest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = reftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my reftest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer reference
|
||||
{
|
||||
auto k = new Klass("me oh my");
|
||||
auto kret = pointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my pointerreftest", val);
|
||||
verifyCount(1, k);
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// null tests
|
||||
{
|
||||
Klass k = null;
|
||||
|
||||
// TODO: add in const versions too
|
||||
enforce(smartpointertest(k) is null, "return was not null");
|
||||
enforce(smartpointerpointertest(k) is null, "return was not null");
|
||||
enforce(smartpointerreftest(k) is null, "return was not null");
|
||||
enforce(smartpointerpointerreftest(k) is null, "return was not null");
|
||||
enforce(nullsmartpointerpointertest(null) == "null pointer",
|
||||
"not null smartpointer pointer");
|
||||
|
||||
enforceThrows( (){ valuetest(k); }, "Failed to catch null pointer");
|
||||
enforce(pointertest(k) is null, "return was not null");
|
||||
enforceThrows( (){ reftest(k); }, "Failed to catch null pointer");
|
||||
}
|
||||
|
||||
// $owner
|
||||
{
|
||||
auto k = pointerownertest();
|
||||
string val = k.getValue();
|
||||
verifyValue("pointerownertest", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
{
|
||||
auto k = smartpointerpointerownertest();
|
||||
string val = k.getValue();
|
||||
verifyValue("smartpointerpointerownertest", val);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
////////////////////////////////// Derived classes ////////////////////////////////////////
|
||||
// derived pass by shared_ptr
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrtest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrtest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr pointer
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrpointertest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrreftest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by shared_ptr pointer ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedsmartptrpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedsmartptrpointerreftest-Derived", val);
|
||||
verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
|
||||
verifyCount(4, kret);
|
||||
}
|
||||
// derived pass by pointer
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedpointertest-Derived", val);
|
||||
verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
// derived pass by ref
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = derivedreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my derivedreftest-Derived", val);
|
||||
verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
|
||||
verifyCount(2, kret);
|
||||
}
|
||||
|
||||
////////////////////////////////// Derived and base class mixed ////////////////////////////////////////
|
||||
// pass by shared_ptr (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointertest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerpointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointertest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr reference (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerreftest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by shared_ptr pointer reference (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = smartpointerpointerreftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my smartpointerpointerreftest-Derived", val);
|
||||
verifyCount(3, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(3, kret);
|
||||
}
|
||||
|
||||
// pass by value (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = valuetest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my valuetest", val); // note slicing
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by pointer (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = pointertest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my pointertest-Derived", val);
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// pass by ref (mixed)
|
||||
{
|
||||
auto k = new KlassDerived("me oh my");
|
||||
auto kret = reftest(k);
|
||||
string val = kret.getValue();
|
||||
verifyValue("me oh my reftest-Derived", val);
|
||||
verifyCount(2, k); // an extra reference for the upcast in the proxy class
|
||||
verifyCount(1, kret);
|
||||
}
|
||||
|
||||
// 3rd derived class
|
||||
{
|
||||
auto k = new Klass3rdDerived("me oh my");
|
||||
string val = k.getValue();
|
||||
verifyValue("me oh my-3rdDerived", val);
|
||||
verifyCount(3, k); // 3 classes in inheritance chain == 3 swigCPtr values
|
||||
val = test3rdupcast(k);
|
||||
verifyValue("me oh my-3rdDerived", val);
|
||||
verifyCount(3, k);
|
||||
}
|
||||
|
||||
////////////////////////////////// Member variables ////////////////////////////////////////
|
||||
// smart pointer by value
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member value");
|
||||
m.SmartMemberValue = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("smart member value", val);
|
||||
verifyCount(2, k);
|
||||
|
||||
auto kmember = m.SmartMemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member value", val);
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
}
|
||||
// smart pointer by pointer
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member pointer");
|
||||
m.SmartMemberPointer = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("smart member pointer", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.SmartMemberPointer;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member pointer", val);
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(2, kmember);
|
||||
verifyCount(2, k);
|
||||
}
|
||||
// smart pointer by reference
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("smart member reference");
|
||||
m.SmartMemberReference = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(2, k);
|
||||
|
||||
auto kmember = m.SmartMemberReference;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
|
||||
// The C++ reference refers to SmartMemberValue...
|
||||
auto kmemberVal = m.SmartMemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("smart member reference", val);
|
||||
verifyCount(4, kmemberVal);
|
||||
verifyCount(4, kmember);
|
||||
verifyCount(4, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(3, kmember);
|
||||
verifyCount(3, k);
|
||||
}
|
||||
// plain by value
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member value");
|
||||
m.MemberValue = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("plain member value", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberValue;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member value", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
// plain by pointer
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member pointer");
|
||||
m.MemberPointer = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("plain member pointer", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberPointer;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member pointer", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
// plain by reference
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
auto k = new Klass("plain member reference");
|
||||
m.MemberReference = k;
|
||||
string val = k.getValue();
|
||||
verifyValue("plain member reference", val);
|
||||
verifyCount(1, k);
|
||||
|
||||
auto kmember = m.MemberReference;
|
||||
val = kmember.getValue();
|
||||
verifyValue("plain member reference", val);
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
|
||||
delete m;
|
||||
|
||||
verifyCount(1, kmember);
|
||||
verifyCount(1, k);
|
||||
}
|
||||
|
||||
// null member variables
|
||||
{
|
||||
auto m = new MemberVariables();
|
||||
|
||||
// shared_ptr by value
|
||||
auto k = m.SmartMemberValue;
|
||||
if (k !is null)
|
||||
throw new Exception("expected null");
|
||||
m.SmartMemberValue = null;
|
||||
k = m.SmartMemberValue;
|
||||
if (k !is null)
|
||||
throw new Exception("expected null");
|
||||
verifyCount(0, k);
|
||||
|
||||
// plain by value
|
||||
enforceThrows( (){ m.MemberValue = null; }, "Failed to catch null pointer");
|
||||
}
|
||||
|
||||
////////////////////////////////// Global variables ////////////////////////////////////////
|
||||
// smart pointer
|
||||
{
|
||||
auto kglobal = GlobalSmartValue;
|
||||
enforce(kglobal is null, "expected null");
|
||||
|
||||
auto k = new Klass("smart global value");
|
||||
GlobalSmartValue = k;
|
||||
verifyCount(2, k);
|
||||
|
||||
kglobal = GlobalSmartValue;
|
||||
string val = kglobal.getValue();
|
||||
verifyValue("smart global value", val);
|
||||
verifyCount(3, kglobal);
|
||||
verifyCount(3, k);
|
||||
verifyValue("smart global value", GlobalSmartValue.getValue());
|
||||
GlobalSmartValue = null;
|
||||
}
|
||||
// plain value
|
||||
{
|
||||
Klass kglobal;
|
||||
|
||||
auto k = new Klass("global value");
|
||||
GlobalValue = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalValue;
|
||||
string val = kglobal.getValue();
|
||||
verifyValue("global value", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
verifyValue("global value", GlobalValue.getValue());
|
||||
|
||||
enforceThrows((){ GlobalValue = null; }, "Failed to catch null pointer");
|
||||
}
|
||||
// plain pointer
|
||||
{
|
||||
auto kglobal = GlobalPointer;
|
||||
enforce(kglobal is null, "expected null");
|
||||
|
||||
auto k = new Klass("global pointer");
|
||||
GlobalPointer = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalPointer;
|
||||
string val = kglobal.getValue();
|
||||
verifyValue("global pointer", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
GlobalPointer = null;
|
||||
}
|
||||
// plain reference
|
||||
{
|
||||
Klass kglobal;
|
||||
|
||||
auto k = new Klass("global reference");
|
||||
GlobalReference = k;
|
||||
verifyCount(1, k);
|
||||
|
||||
kglobal = GlobalReference;
|
||||
string val = kglobal.getValue();
|
||||
verifyValue("global reference", val);
|
||||
verifyCount(1, kglobal);
|
||||
verifyCount(1, k);
|
||||
|
||||
enforceThrows((){ GlobalReference = null; }, "Failed to catch null pointer");
|
||||
}
|
||||
|
||||
////////////////////////////////// Templates ////////////////////////////////////////
|
||||
{
|
||||
auto pid = new PairIntDouble(10, 20.2);
|
||||
enforce(pid.baseVal1 == 20 && pid.baseVal2== 40.4, "Base values wrong");
|
||||
enforce(pid.val1 == 10 && pid.val2 == 20.2, "Derived Values wrong");
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyValue(string expected, string got) {
|
||||
if (expected != got)
|
||||
throw new Exception("verify value failed. Expected: " ~ expected ~ " Got: " ~ got);
|
||||
}
|
||||
|
||||
private void verifyCount(int expected, Klass k) {
|
||||
// We deliberately call the use_count(Klass) overload also for objects which
|
||||
// are instances of a subclass of Klass (due to static dispatch); things still
|
||||
// have to work.
|
||||
int got = use_count(k);
|
||||
if (expected != got)
|
||||
throw new Exception("verify use_count failed. Expected: " ~ to!string(expected) ~ " Got: " ~ to!string(got));
|
||||
}
|
||||
|
||||
private void enforceThrows(void delegate() dg, string errorMessage) {
|
||||
bool hasThrown;
|
||||
try {
|
||||
dg();
|
||||
} catch (Exception) {
|
||||
hasThrown = true;
|
||||
} finally {
|
||||
if (!hasThrown) {
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
module li_std_except_runme;
|
||||
|
||||
import tango.core.Exception;
|
||||
import tango.io.Console;
|
||||
import li_std_except.Test;
|
||||
|
||||
void main() {
|
||||
with (new Test()) {
|
||||
mixin(test("Exception", "throw_bad_exception"));
|
||||
mixin(test("Exception", "throw_domain_error"));
|
||||
mixin(test("Exception", "throw_exception"));
|
||||
mixin(test("IllegalArgumentException", "throw_invalid_argument"));
|
||||
mixin(test("NoSuchElementException", "throw_length_error"));
|
||||
mixin(test("Exception", "throw_logic_error"));
|
||||
mixin(test("NoSuchElementException", "throw_out_of_range"));
|
||||
mixin(test("Exception", "throw_overflow_error"));
|
||||
mixin(test("Exception", "throw_range_error"));
|
||||
mixin(test("Exception", "throw_runtime_error"));
|
||||
mixin(test("Exception", "throw_underflow_error"));
|
||||
}
|
||||
}
|
||||
|
||||
char[] test(char[] e, char[] f) {
|
||||
return "if (!works!(" ~ e ~ ")(&" ~ f ~ ")) {\n" ~
|
||||
"throw new Exception(\"" ~ f ~ " failed\");\n" ~
|
||||
"}";
|
||||
}
|
||||
|
||||
bool works(alias E, F)(F f) {
|
||||
try {
|
||||
try {
|
||||
f();
|
||||
} catch(E) {
|
||||
return true;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Cerr( "Received wrong exception: " ~ e.classinfo.name ).newline;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
module li_std_except_runme;
|
||||
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
import li_std_except.Test;
|
||||
|
||||
void main() {
|
||||
with (new Test()) {
|
||||
enforce(works!(Exception)(&throw_bad_exception));
|
||||
enforce(works!(Exception)(&throw_domain_error));
|
||||
enforce(works!(Exception)(&throw_exception));
|
||||
enforce(works!(Exception)(&throw_invalid_argument));
|
||||
enforce(works!(Exception)(&throw_length_error));
|
||||
enforce(works!(Exception)(&throw_logic_error));
|
||||
enforce(works!(Exception)(&throw_out_of_range));
|
||||
enforce(works!(Exception)(&throw_overflow_error));
|
||||
enforce(works!(Exception)(&throw_range_error));
|
||||
enforce(works!(Exception)(&throw_runtime_error));
|
||||
enforce(works!(Exception)(&throw_underflow_error));
|
||||
}
|
||||
}
|
||||
|
||||
bool works(alias E, F)(F f) {
|
||||
try {
|
||||
try {
|
||||
f();
|
||||
} catch(E) {
|
||||
return true;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
writefln( "Received wrong exception: %s", e.classinfo.name );
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
module li_std_string_runme;
|
||||
|
||||
import tango.core.Exception;
|
||||
import li_std_string.li_std_string;
|
||||
import li_std_string.Structure;
|
||||
import li_std_string.SWIGTYPE_p_std__string;
|
||||
|
||||
|
||||
void main() {
|
||||
// Checking expected use of %typemap(in) std::string {}
|
||||
test_value("Fee");
|
||||
|
||||
// Checking expected result of %typemap(out) std::string {}
|
||||
if (test_value("Fi") != "Fi")
|
||||
throw new Exception("Test 1 failed");
|
||||
|
||||
// Verify type-checking for %typemap(in) std::string {}
|
||||
try {
|
||||
test_value(null);
|
||||
throw new Exception("Test 2 failed");
|
||||
} catch (IllegalArgumentException) {
|
||||
}
|
||||
|
||||
// Checking expected use of %typemap(in) const std::string & {}
|
||||
test_const_reference("Fo");
|
||||
|
||||
// Checking expected result of %typemap(out) const std::string& {}
|
||||
if (test_const_reference("Fum") != "Fum")
|
||||
throw new Exception("Test 3 failed");
|
||||
|
||||
// Verify type-checking for %typemap(in) const std::string & {}
|
||||
try {
|
||||
test_const_reference(null);
|
||||
throw new Exception("Test 4 failed");
|
||||
} catch (IllegalArgumentException) {
|
||||
}
|
||||
|
||||
// Input and output typemaps for pointers and non-const references to
|
||||
// std::string are *not* supported; the following tests confirm
|
||||
// that none of these cases are slipping through.
|
||||
|
||||
SWIGTYPE_p_std__string stringPtr = null;
|
||||
|
||||
stringPtr = test_pointer_out();
|
||||
test_pointer(stringPtr);
|
||||
|
||||
stringPtr = test_const_pointer_out();
|
||||
test_const_pointer(stringPtr);
|
||||
|
||||
stringPtr = test_reference_out();
|
||||
test_reference(stringPtr);
|
||||
|
||||
// Check throw exception specification
|
||||
try {
|
||||
test_throw();
|
||||
throw new Exception("test 5 failed!");
|
||||
} catch (Exception e) {
|
||||
if (e.msg != "test_throw message")
|
||||
throw new Exception("Test 5 string check: " ~ e.msg);
|
||||
}
|
||||
try {
|
||||
test_const_reference_throw();
|
||||
throw new Exception("test 6 failed!");
|
||||
} catch (Exception e) {
|
||||
if (e.msg != "test_const_reference_throw message")
|
||||
throw new Exception("Test 6 string check: " ~ e.msg);
|
||||
}
|
||||
|
||||
// Global variables.
|
||||
const char[] s = "initial string";
|
||||
if (GlobalString2 != "global string 2")
|
||||
throw new Exception("GlobalString2 test 1");
|
||||
GlobalString2 = s;
|
||||
if (GlobalString2 != s)
|
||||
throw new Exception("GlobalString2 test 2");
|
||||
if (ConstGlobalString != "const global string")
|
||||
throw new Exception("ConstGlobalString test");
|
||||
|
||||
// Member variables.
|
||||
auto myStructure = new Structure();
|
||||
if (myStructure.MemberString2 != "member string 2")
|
||||
throw new Exception("MemberString2 test 1");
|
||||
myStructure.MemberString2 = s;
|
||||
if (myStructure.MemberString2 != s)
|
||||
throw new Exception("MemberString2 test 2");
|
||||
if (myStructure.ConstMemberString != "const member string")
|
||||
throw new Exception("ConstMemberString test");
|
||||
|
||||
// Static member variables.
|
||||
if (Structure.StaticMemberString2 != "static member string 2")
|
||||
throw new Exception("StaticMemberString2 test 1");
|
||||
Structure.StaticMemberString2 = s;
|
||||
if (Structure.StaticMemberString2 != s)
|
||||
throw new Exception("StaticMemberString2 test 2");
|
||||
if (Structure.ConstStaticMemberString != "const static member string")
|
||||
throw new Exception("ConstStaticMemberString test");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue