#!/usr/local/bin/perl
#
# obj2ptr
# Copyright (C) 1997 Norio Katayama
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# 06/08/96 katayama@rd.nacsis.ac.jp
# $Id: obj2ptr,v 1.1.1.1 1998/08/28 11:28:16 katayama Exp $
#

($program = $0) =~ s|^.*/||;

$usage = <<"EOF";
Usage: $program objHdrFile
EOF
    ;

if(@ARGV != 1) {
    die $usage;
}
$objHdrFile = $ARGV[0];

#
# obtain class names
#

($objClass = $objHdrFile) =~ s|^.*/||;
$objClass =~ s|\.[^\.]+$||;

unless(($ptrHdrFile = $objHdrFile) =~ s/Obj\.hh/.hh/) {
    die("$program: object header file name must end with `Obj.hh', stopped");
}
($ptrSrcFile = $ptrHdrFile) =~ s/\.hh/\.cc/;
($ptrClass = $ptrHdrFile) =~ s|^.*/||;
$ptrClass =~ s|\.[^\.]+$||;

#
# obtain public fields
#

open(HANDLE, $objHdrFile) ||
    die("$program: cannot open `$objHdrFile'.\n");

while(<HANDLE>) {
    s/\n$//;
    if(/^class\s+$objClass[\s:]/) {
	#
	# obtain super class
	#
	s/^class\s+$objClass\s*:\s*//;
	if(/^public\s+([A-Za-z_][A-Za-z_0-9]*)\s+\{$/) {
	    $objSuperClass = $1;
	    if($objSuperClass eq "HnObject") {
		$ptrSuperClass = 'HnPointer';
	    }
	    elsif($objSuperClass =~ /^(.*)Obj$/) {
		$ptrSuperClass = $1;
	    }
	    else {
		die("$program: unexpected super class `$objSuperClass', ".
		    "stopped");
	    }
	}
	&parseClass;
    }
    elsif(/^\/\*\{$/) {
	&getPreamble;
    }
}

close(HANDLE);

&generateHdrFile;
&generateSrcFile;

exit 0;

#
# get preamble
#

sub getPreamble {
    while(<HANDLE>) {
	s/\n$//;
	if(/^\}\*\/$/) {
	    return 1;
	}
	else {
	    push(@preambles, $_);
	}
    }

    die("$program: cannot find the end of the preamble, stopped");
}

#
# parse class
#

sub parseClass {
    local($inPublic);

    while(<HANDLE>) {
	s/\n$//;
	if(/^public:$/) {
	    $inPublic = 1;
	}
	elsif(/^private:$/) {
	    $inPublic = 0;
	}
	elsif(/^\};$/) {
	    return 1;
	}
	elsif($inPublic) {
	    if(/^\s*$objClass\s*\(/) {
		&getConstructor;
	    }
	    elsif(/\(/) {
		&getFunction;
	    }
	    elsif(/^\/\*\{$/) {
		&getEmbedded;
	    }
	    else {
		push(@fields, $_);
	    }
	}
    }

    die("$program: cannot find the end of the class definition, stopped");
}

#
# get constructor
#

sub getConstructor {
    # find close parenthesis
    while(!/\)/) {
	push(@fields, $_);
	$_ = <HANDLE>;
	s/\n$//;
    }

    s/([^\)]*\))\s*//;
    push(@fields, "$1;");

    # find open brace or semi-colon
    while(!/\{/ && !/;/) {
	$_ = <HANDLE>;
	s/\n$//;
    }

    #
    # remove inline
    #
    if(/\{/) {
	# find balanced close brace
	do {
	    if(s/^[^\{\}]*\{[^\{\}]*//) {
		$level ++;
	    }
	    elsif(s/^[^\{\}]*\}[^\{\}]*//) {
		$level --;
	    }
	    else {
		$_ .= <HANDLE>;
		s/\n$//;
	    }
	} while($level != 0);
    }
}

#
# get function 
#

sub getFunction {
    # remove the keyword `virtual'
    s/^(\s*)virtual\s+/$1/;

    # find close parenthesis
    while(!/\)/) {
	push(@fields, $_);
	$_ = <HANDLE>;
	s/\n$//;
    }

    # remove the pure specifier
    s/\)\s*=\s*0\s*;/);/;

    # find open brace or semi-colon
    while(!/\{/ && !/;/) {
	push(@fields, $_);
	$_ = <HANDLE>;
	s/\n$//;
    }
    #
    # remove inline
    #
    if(/\{/) {
	s/([^\{]+)\s+\{/\{/;
	push(@fields, "$1;");

	# find balanced close brace
	do {
	    if(s/^[^\{\}]*\{[^\{\}]*//) {
		$level ++;
	    }
	    elsif(s/^[^\{\}]*\}[^\{\}]*//) {
		$level --;
	    }
	    else {
		$_ .= <HANDLE>;
		s/\n$//;
	    }
	} while($level != 0);
    }
    else {
	push(@fields, $_);
    }
}

#
# get embedded
#

sub getEmbedded {
    while(<HANDLE>) {
	s/\n$//;
	if(/^\}\*\/$/) {
	    return 1;
	}
	else {
	    push(@embedded, $_);
	}
    }

    die("$program: cannot find the end of the embedded declaration, stopped");
}

#
# generate header file
#

sub generateHdrFile {
    local(@fields) = @fields;
    local($sec, $min, $hour, $mday, $mon, $year) = (localtime)[0..5];
    local($when) = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
			   $year + 1900, $mon + 1, $mday, $hour, $min, $sec);

    open(HANDLE, ">$ptrHdrFile") ||
	die("$program: cannot open `$ptrHdrFile', stopped");

    print HANDLE <<"EOF";
/*
 * $ptrHdrFile
 *
 * DO NOT EDIT THIS FILE!
 *
 * This file is automatically generated by $program.
 * $when
 */

#ifndef _${ptrClass}_hh
#define _${ptrClass}_hh

#include "$ptrSuperClass.hh"

EOF

    if(@preambles) {
	foreach(@preambles) {
	    print HANDLE $_, "\n";
	}
	print HANDLE "\n";
    }

    print HANDLE <<"EOF";
/*
 * $ptrClass
 */

class $ptrClass: public $ptrSuperClass {
private:
    friend class $objClass;
	$ptrClass(const $objClass *ptr) {
		HnPointer::assign((HnObject *)ptr);
	}
	$objClass *getObject(void) const {
		return ($objClass *)HnPointer::getObject();
	}
public:
	static const $ptrClass null;
	$ptrClass(void) {}
public:
EOF

    if(@embedded != 0) {
	foreach(@embedded) {
	    print HANDLE $_, "\n";
	}
	print HANDLE "\n";
    }

    foreach(@fields) {
	if(s/^(\s*)$objClass\s*\(/    friend $ptrClass\n${1}new_$ptrClass\(/) {
	    # constructor
	    print HANDLE $_, "\n";
	}
	elsif(/^\s*~$objClass\s*\(/) {
	    # ignore destructor
	}
	else {
	    print HANDLE $_, "\n";
	}
    }

    if($ptrClass eq "HnString") {
	print HANDLE <<"EOF";

	HnString toString(void) const {
		if(isInvalid())
			return "HnString::null";
    		else
			return *this;
	}
EOF
    }

    print HANDLE <<"EOF";
};

/*
 * ${ptrClass}Array
 */

class ${ptrClass}Array: public HnPointer {
private:
    friend class ${ptrClass}ArrayObj;
	${ptrClass}Array(const ${ptrClass}ArrayObj *ptr) {
		HnPointer::assign((HnObject *)ptr);
	}
	${ptrClass}ArrayObj *getObject(void) const {
		return (${ptrClass}ArrayObj *)HnPointer::getObject();
	}
public:
	static const ${ptrClass}Array null;
	${ptrClass}Array(void) {}
public:
	/* constructors */
    friend ${ptrClass}Array
	new_${ptrClass}Array(void);
    friend ${ptrClass}Array
	new_${ptrClass}Array(const ${ptrClass}Array &ptr);

	/* clear, append, insert, and remove */
	void clear(void);
	void append(const $ptrClass &ptr);
	void append(const ${ptrClass}Array &ptr);
	void insert(const $ptrClass &ptr, int index);
	$ptrClass remove(int index);
	void set(const $ptrClass &ptr, int index);
	void swap(int i, int j);

	/* length and get */
	int length(void) const;
	$ptrClass &get(int i) const;
	$ptrClass &operator[](int i) const { return get(i); }

	/* utilities */
	void push(const $ptrClass &ptr) {
		append(ptr);
	}
	$ptrClass pop(void) {
		return remove(length() - 1);
	}
	HnBool equals(const ${ptrClass}Array &ptr) const;
	int indexOf(const $ptrClass &ptr, int fromIndex) const;
	int indexOf(const $ptrClass &ptr) const  {
	    return indexOf(ptr, 0);
	}
	HnString toString(void) const;
};

#endif /* _${ptrClass}_hh */
EOF

    close(HANDLE);

    1;
}

#
# generate source file
#

sub generateSrcFile {
    local(@fields) = @fields;
    local($sec, $min, $hour, $mday, $mon, $year) = (localtime)[0..5];
    local($when) = sprintf("%04d/%02d/%02d %02d:%02d:%02d",
			   $year + 1900, $mon + 1, $mday, $hour, $min, $sec);

    open(HANDLE, ">$ptrSrcFile") ||
	die("$program: cannot open `$ptrSrcfile', stopped");

    print HANDLE <<"EOF";
/*
 * $ptrSrcFile
 *
 * DO NOT EDIT THIS FILE!
 *
 * This file is automatically generated by $program.
 * $when
 */

#include "$ptrHdrFile"
#include "$objHdrFile"

/*
 * $ptrClass
 */

const $ptrClass $ptrClass::null;

EOF
    ;

    while(@fields) {
	# remove comment
	$_ = shift(@fields);
	next if(/\/\//);
	if(/\/\*/) {
	    while(!/\*\//) {
		$_ = shift(@fields);
	    }
	    $_ = shift(@fields);
	}

	# find open parenthesis
	if(/\(/) {
	    # find close parenthesis
	    while(!/\)/) {
		$_ .= shift(@fields);
	    }

	    # find semi-colon
	    while(!/;/) {
		$_ .= shift(@fields);
	    }

	    &generateStub($_);
	}
    }

    &generateArray;	

    close(HANDLE);

    1;
}

#
# generate stub
#

sub generateStub {
    if(@_ != 1) {
	die("$program: generateStub() requires one argument, stopped");
    }
    local($returnType, $methodName, $qualifier);
    $_ = @_[0];

    # return type and method name
    if(s/\s*([^\(]*[^A-Za-z_~])(operator[^A-Za-z_~\(][^\(]*)\(//) {
	($returnType = $1) =~ s/\s*$//;
	($methodName = $2) =~ s/\s*$//;
    }
    elsif(s/\s*([^\(]*[^A-Za-z_0-9~])([A-Za-z_~][A-Za-z_0-9]*)\s*\(//) {
	($returnType = $1) =~ s/\s*$//;
	($methodName = $2) =~ s/\s*$//;
    }
    else {
	die("$program: cannot find function name at `$_', stopped");
    }

    # parameters
    @params = ();
    while(s/\s*([^,\)]+),//) {
	push(@params, $1);
    }
    unless(s/\s*([^,\)]+)\)//) {
	die("$program: cannot find parameter list at `$_', stopped");
    }
    push(@params, $1);

    # qualifier
    if(s/\s*([^\s].*)\s*;//) {
	$qualifier = $1;
    }

    # variables
    if(@params == 1 && $params[0] eq "void") {
	@variables = ();
    }
    else {
	@variables = ();
	foreach(@params) {
	    if(/[^=]*[^A-Za-z_\d~]([A-Za-z_~][A-Za-z_\d]*)(\[\])?(\s*=.*)?$/) {
		push(@variables, $1);
	    }
	    else {
		die("$program: cannot find variable at `$_', stopped");
	    }
	}
    }

    if($methodName eq "$objClass") {
	&generateConstructorStub;
    }
    elsif($methodName eq "~$objClass") {
	# ignore
    }
    elsif($methodName eq "equals") {
	&generateEqualsStub;
    }
    elsif($methodName eq "toString") {
	&generateToStringStub;
    }
    elsif($methodName =~ /^operator/) {
	&generateOperatorStub;
    }
    elsif($returnType =~ s/^static\s+//) {
	&generateClassMethodStub;
    }
    else {
	&generateNormalStub;
    }
}

#
# generate constructor stub
#

sub generateConstructorStub {
    print HANDLE "$ptrClass\n";
    print HANDLE "new_$ptrClass(";
    for($i=0; $i<@params; $i++) {
	print HANDLE ", " if ($i != 0);

	# remove default argument
	($param = $params[$i]) =~ s/\s*=.*$//;
	print HANDLE $param;
    }
    print HANDLE ")\n";
    print HANDLE "{\n";
    print HANDLE "	$objClass *_obj;\n";
    print HANDLE "	$ptrClass _ptr;\n";
    print HANDLE "\n";
    print HANDLE "	_obj = new $objClass(";
    for($i=0; $i<@variables; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $variables[$i];
    }
    print HANDLE ");\n";
    print HANDLE "\n";
    print HANDLE "	if(_obj->hasFailed())\n";
    print HANDLE "		return $ptrClass::null;\n";
    print HANDLE "\n";
    print HANDLE "	_ptr.assign(_obj);\n";
    print HANDLE "	return _ptr;\n";
    print HANDLE "}\n";
    print HANDLE "\n";
}

#
# generate equals stub
#

sub generateEqualsStub {
    if($returnType ne "HnBool") {
	die("$program: the return type of equals() must be HnBool, stopped");
    }
    if(@params != 1 || !($params[0] =~ /const $ptrClass &$variables[0]/)) {
	die("$program: the parameter type of equals() must be ".
	    "`const $ptrClass &', stopped");
    }
    print HANDLE <<"EOF";
HnBool
$ptrClass::equals(const $ptrClass &ptr) const {
	if(isInvalid()) {
		if(ptr.isInvalid())
			return HnTRUE;
		else
			return HnFALSE;
    	}
    	else {
		if(ptr.isInvalid())
			return HnFALSE;
		else
			return getObject()->equals(ptr);
	}
}

EOF
}

#
# generate toString stub
#

sub generateToStringStub {
    if($returnType ne "HnString") {
	die("$program: the return type of toString() must be HnString, ".
	    "stopped");
    }
    if(@params != 1 || !($params[0] eq "void")) {
	die("$program: the paramter of toString() must be `void', stopped");
    }
    print HANDLE <<"EOF";
HnString
$ptrClass::toString(void) const {
	if(isInvalid())
		return "$ptrClass::null";
    	else
		return getObject()->toString();
}

EOF
    ;
}

#
# generate normal stub
#

sub generateNormalStub {
    print HANDLE "$returnType\n";
    print HANDLE "$ptrClass::$methodName(";
    for($i=0; $i<@params; $i++) {
	print HANDLE ", " if ($i != 0);

	# remove default argument
	($param = $params[$i]) =~ s/\s*=.*$//;
	print HANDLE $param;
    }
    print HANDLE ")";
    print HANDLE " $qualifier" if ($qualifier);
    print HANDLE "\n";
    print HANDLE "{\n";
    if($returnType eq "void") {
	print HANDLE "	";
    }
    else {
	print HANDLE "	return ";
    }   
    print HANDLE "getObject()->$methodName(";
    for($i=0; $i<@variables; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $variables[$i];
    }
    print HANDLE ");\n";
    print HANDLE "}\n";
    print HANDLE "\n";
}

#
# generate operator stub
#

sub generateOperatorStub {
    if("$returnType" ne "") {
	print HANDLE "$returnType\n";
    }
    print HANDLE "$ptrClass::$methodName(";
    for($i=0; $i<@params; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $params[$i];
    }
    print HANDLE ")";
    print HANDLE " $qualifier" if ($qualifier);
    print HANDLE "\n";
    print HANDLE "{\n";
    if($returnType eq "void") {
	print HANDLE "	";
    }
    else {
	print HANDLE "	return ";
    }   
    print HANDLE "getObject()->$methodName(";
    for($i=0; $i<@variables; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $variables[$i];
    }
    print HANDLE ");\n";
    print HANDLE "}\n";
    print HANDLE "\n";
}

#
# generate class method stub
#

sub generateClassMethodStub {
    print HANDLE "$returnType\n";
    print HANDLE "$ptrClass::$methodName(";
    for($i=0; $i<@params; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $params[$i];
    }
    print HANDLE ")";
    print HANDLE " $qualifier" if ($qualifier);
    print HANDLE "\n";
    print HANDLE "{\n";
    if($returnType eq "void") {
	print HANDLE "	";
    }
    else {
	print HANDLE "	return ";
    }   
    print HANDLE "$objClass::$methodName(";
    for($i=0; $i<@variables; $i++) {
	print HANDLE ", " if ($i != 0);
	print HANDLE $variables[$i];
    }
    print HANDLE ");\n";
    print HANDLE "}\n";
    print HANDLE "\n";
}

#
# generate array
#

sub generateArray {
    print HANDLE <<"EOF";
/*
 * ${ptrClass}ArrayObj
 */

#include <stdlib.h>
EOF

    if($ptrClass ne "HnString") {
	print HANDLE '#include "HnString.hh"', "\n";
    }

    print HANDLE <<"EOF";
class ${ptrClass}ArrayObj: public HnObject {
private:
	$ptrClass **array;
	int len;
	int size;

	static const int initialSize;

	void initialize(void) {
		array = NULL;
		len = 0;
		size = 0;
	}
	void dispose(void) {
		if(array != NULL) {
			int i;
			for(i=0; i<len; i++)
				delete array[i];
			free(array);
		}
		array = NULL;
		len = 0;
		size = 0;
	}
	void ensureSize(int requiredSize);

public:
	/* constructor and destructor */
	${ptrClass}ArrayObj(void);
	${ptrClass}ArrayObj(const ${ptrClass}Array &ptr);
	~${ptrClass}ArrayObj(void);

	/* clear, append, insert, and remove */
	void clear(void);
	void append(const $ptrClass &ptr);
	void append(const ${ptrClass}Array &ptr);
	void insert(const $ptrClass &ptr, int index);
	$ptrClass remove(int index);
	void set(const $ptrClass &ptr, int index);
	void swap(int i, int j);

	/* length and get */
	int length(void) const { return len; }
	$ptrClass &get(int i) const;

	/* utilities */
	HnBool equals(const ${ptrClass}Array &ptr) const;
	int indexOf(const $ptrClass &ptr, int fromIndex) const;
	HnString toString(void) const;
};

const int ${ptrClass}ArrayObj::initialSize = 4;

static void *
xrealloc(void *ptr, size_t size)
{
        if(ptr == NULL) {
                if((ptr = malloc(size)) == NULL)
                        HnSysError("malloc");
        }
        else {
                if((ptr = realloc(ptr, size)) == NULL)
                        HnSysError("realloc");
        }

        return ptr;
}

void
${ptrClass}ArrayObj::ensureSize(int requiredSize)
{
	int oldSize, newSize;

	if((oldSize = size) >= requiredSize)
		return;

	if((newSize = oldSize) == 0)
		newSize = initialSize;

	while(newSize < requiredSize)
		newSize *= 2;

	array = ($ptrClass **)xrealloc(array, sizeof($ptrClass *) * newSize);

	size = newSize;
}

${ptrClass}ArrayObj::${ptrClass}ArrayObj(void)
{
	initialize();
}

${ptrClass}ArrayObj::${ptrClass}ArrayObj(const ${ptrClass}Array &ptr)
{
	initialize();

	clear();
	append(ptr);
}

${ptrClass}ArrayObj::~${ptrClass}ArrayObj(void)
{
	dispose();
}

void
${ptrClass}ArrayObj::clear(void)
{
	dispose();
}

void
${ptrClass}ArrayObj::append(const $ptrClass &ptr)
{
	ensureSize(len + 1);

	array[len] = new $ptrClass(ptr);
	len ++;
}

void
${ptrClass}ArrayObj::append(const ${ptrClass}Array &ptr)
{
	int i;

	ensureSize(len + ptr.length());

	for(i=0; i<ptr.length(); i++)
		append(ptr[i]);
}

void
${ptrClass}ArrayObj::insert(const $ptrClass &ptr, int index)
{
	if(index < 0 || index > len)
		HnAbort("${ptrClass}ArrayObj::insert: "
			"index is out of bounds.");

	ensureSize(len + 1);

	memmove(array + index + 1, array + index,
		sizeof($ptrClass *) * (len - index));

	array[index] = new $ptrClass(ptr);
	len ++;
}

$ptrClass
${ptrClass}ArrayObj::remove(int index)
{
	$ptrClass ptr = get(index);

	if(index < 0 || index >= len)
                HnAbort("${ptrClass}ArrayObj::remove: "
			"index is out of bounds.");

	delete array[index];

	memmove(array + index, array + index + 1,
		sizeof($ptrClass *) * (len - index - 1));
	len --;

	return ptr;
}

void
${ptrClass}ArrayObj::set(const $ptrClass &ptr, int index)
{
	if(index < 0 || index >= len)
		HnAbort("${ptrClass}ArrayObj::set: "
			"index is out of bounds.");

	delete array[index];

	array[index] = new $ptrClass(ptr);
}

void
${ptrClass}ArrayObj::swap(int i, int j)
{
	if(i < 0 || i >= len || j < 0 || j >= len)
		HnAbort("${ptrClass}ArrayObj::swap: index is out of bounds.");

	$ptrClass *ptr = array[i];
	array[i] = array[j];
	array[j] = ptr;
}

$ptrClass &
${ptrClass}ArrayObj::get(int i) const {
	if(i < 0 || i >= len)
		HnAbort("${ptrClass}ArrayObj::get: index is out of bounds.");

	return *array[i];
}

HnBool
${ptrClass}ArrayObj::equals(const ${ptrClass}Array &ptr) const {
	int i;

	if(len != ptr.length())
		return HnFALSE;

	for(i=0; i<len; i++) {
		if(!array[i]->equals(ptr[i]))
			return HnFALSE;
	}

	return HnTRUE;
}

int
${ptrClass}ArrayObj::indexOf(const $ptrClass &ptr, int fromIndex) const
{
	int i;

	for(i=fromIndex; i<len; i++) {
		if(array[i]->equals(ptr))
			return i;
	}

	return -1;
}

HnString
${ptrClass}ArrayObj::toString(void) const
{
	HnString string;

	string = "[ ";
	for(int i=0; i<len; i++) {
		if(i != 0)
			string += ", ";
		string += array[i]->toString();
	}
	string += " ]";

	return string;
}

/*
 * ${ptrClass}Array
 */

const ${ptrClass}Array ${ptrClass}Array::null;

${ptrClass}Array
new_${ptrClass}Array(void)
{
	${ptrClass}Array ptr;

        ptr.assign(new ${ptrClass}ArrayObj());
        return ptr;
}

${ptrClass}Array
new_${ptrClass}Array(const ${ptrClass}Array &value)
{
	${ptrClass}Array ptr;

        if(value.isInvalid())
                ptr.assign(NULL);
        else
                ptr.assign(new ${ptrClass}ArrayObj(value));

        return ptr;
}

void
${ptrClass}Array::clear(void)
{
	getObject()->clear();
}

void
${ptrClass}Array::append(const $ptrClass &ptr)
{
	getObject()->append(ptr);
}

void
${ptrClass}Array::append(const ${ptrClass}Array &ptr)
{
	getObject()->append(ptr);
}

void
${ptrClass}Array::insert(const $ptrClass &ptr, int index)
{
	getObject()->insert(ptr, index);
}

$ptrClass
${ptrClass}Array::remove(int index)
{
	return getObject()->remove(index);
}

void
${ptrClass}Array::set(const $ptrClass &ptr, int index)
{
	getObject()->set(ptr, index);
}

void
${ptrClass}Array::swap(int i, int j)
{
	getObject()->swap(i, j);
}

int
${ptrClass}Array::length(void) const
{
	return getObject()->length();
}

$ptrClass &
${ptrClass}Array::get(int i) const
{
	return getObject()->get(i);
}

HnBool
${ptrClass}Array::equals(const ${ptrClass}Array &ptr) const
{
	return getObject()->equals(ptr);
}

int
${ptrClass}Array::indexOf(const $ptrClass &ptr, int fromIndex) const
{
	return getObject()->indexOf(ptr, fromIndex);
}

HnString
${ptrClass}Array::toString(void) const
{
	return getObject()->toString();
}

EOF
    ;

}
