Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

comparison between class(*) instances

237 views
Skip to first unread message

GianLuigi Piacentini

unread,
Dec 28, 2020, 8:25:21 PM12/28/20
to
I would like to compare for equality 2 instances of class(*), having the
same - but unknown - dynamic type, like
logical function compare_star (a, b)
class(*), intent(in) :: a, b
compare_star = a == b

gfortran does not allow this (probably is not allowed by the standard, too).

Any suggestion ? Thanks in advance, and, as we say here in Italy
"Buon Anno"

Gigi

gah4

unread,
Dec 28, 2020, 11:29:51 PM12/28/20
to
On Monday, December 28, 2020 at 5:25:21 PM UTC-8, GianLuigi Piacentini wrote:
> I would like to compare for equality 2 instances of class(*), having the
> same - but unknown - dynamic type, like
> logical function compare_star (a, b)
> class(*), intent(in) :: a, b
> compare_star = a == b

> gfortran does not allow this (probably is not allowed by the standard, too).

In Java, if you compare two variables, you would actually compare the
references to them. (Pointers in other languages).

Many classes have a equals() method that will compare two instances
of a class. Otherwise, there is no way for the system to know what you mean
by compare.

I am not so sure how it would work in OO Fortran, though, but you would want
a equals() method with appropriate subclassing.



Ev. Drikos

unread,
Dec 29, 2020, 1:37:16 AM12/29/20
to
On 29/12/2020 06:29, gah4 wrote:
> On Monday, December 28, 2020 at 5:25:21 PM UTC-8, GianLuigi Piacentini wrote:
>> I would like to compare for equality 2 instances of class(*), having the
>> same - but unknown - dynamic type, like
>> logical function compare_star (a, b)
>> class(*), intent(in) :: a, b
>> compare_star = a == b
>
>> gfortran does not allow this (probably is not allowed by the standard, too).
>
> In Java, if you compare two variables, you would actually compare the
> references to them. (Pointers in other languages).
>
So far, so good.

> Many classes have a equals() method that will compare two instances
> of a class. Otherwise, there is no way for the system to know what you mean
> by compare.

To work ie with containers, the interface Comparable is also available.

In Java the class Object is a super-class of all other classes (apart
the primitive types, ie int, boolean, ...) that implements the interface
Comparable. So, each subclass can declare that implements the interface
and provide the method compareTo.

Various containers, like TreeMap or TreeSet ie, can then keep instances
of such classes in an organized manner. This works without templates.

> I am not so sure how it would work in OO Fortran, though, but you would want
> a equals() method with appropriate subclassing.
>

Indeed it's a question how this can work without containers/overloading.


Ev. Drikos

FortranFan

unread,
Dec 29, 2020, 9:48:21 AM12/29/20
to
On Monday, December 28, 2020 at 8:25:21 PM UTC-5, GianLuigi Piacentini wrote:

> I would like to compare for equality 2 instances of class(*), having the
> same - but unknown - dynamic type..
> Any suggestion ? ..

@GianLuigi Piacentini,

Given your point about "Any suggestion ", you may want to consider also inquiring at the Fortran Discourse site which can provide you with at least advantages: 1) get wider feedback on your Fortran-related question and 2) that forum provides options for syntax-highlighted code, images and other attachments, making it easier for community engagement.
https://fortran-lang.discourse.group/

As to your question, you may want to provide more detailed context as to why need such a function, especially because in practical codes it will make sense to eschew the unlimited polymorphic (CLASS(*)) dummy argument option.

Re: direct comparison of unlimited polymorphic dummy arguments, as you noted, it "is not allowed by the standard". You will have to "cast" the dummy arguments via a SELECT TYPE construct which you will likely find to be too verbose or unwieldy for you will need to make sure to case every type and kind you intend to support with the procedure:

logical function compare_star (a, b)
class(*), intent(in) :: a, b

select type ( a )
type is ( integer(kind=k1) )
select type ( b)
type is ( ( integer(kind=k1) )
compare_star = a == b
type is ( ( integer(kind=k2) )
compare_star = a == b
..
..

Moreover, if you intend the overload the equatily operator(==), you will need to be careful with your compiler version for there are some processors with unresolved bugs with processing of the operator within the SELECT TYPE construct leading to infinite recursion.

Ev. Drikos

unread,
Dec 29, 2020, 10:35:23 AM12/29/20
to
On 29/12/2020 08:37, Ev. Drikos wrote:

>
> Indeed it's a question how this can work without containers/overloading.

Sorry, it's a question how this can work without templates/overloading.

> Ev. Drikos

spectrum

unread,
Dec 29, 2020, 7:22:23 PM12/29/20
to
Just for fun, I've tried comparison between class(*) variables below, but rejected by
Gfortran, as expected...

What I found interesting is that an assignment between
two variables of the same type is allowed (maked as "L-1" in the code below),
while their comparison is not allowed (marked as "L-2").
Does this mean that bitwise comparison does not work for such cases?

(I'm wondering if there is padding between type components,
bitwise comparison may give unpredictable results because of
garbage values for the padded parts?)

program main
implicit none
type Type1
integer :: n1
endtype
type Type2
integer :: n2
endtype

class(*), allocatable :: a, b, x
integer :: id

a = Type1( n1 = 100 )
b = Type2( n2 = 200 )

print *, same_type_as( a, a ) !! T
print *, same_type_as( b, b ) !! T
print *, same_type_as( a, b ) !! F

print *, "Input id:"; read *, id
if ( id == 1 ) x = Type1( n1 = 0 )
if ( id == 2 ) x = Type2( n2 = 0 )

if ( same_type_as( x, a ) ) then
x = a !! works (L-1)
print *, x == a !! illegal (comparison for CLASS(*)/CLASS(*)) (L-2)
endif

if ( same_type_as( x, b ) ) x = b !! works

selecttype ( x )
type is ( Type1 ); print *, x % n1
type is ( Type2 ); print *, x % n2
endselect
end

Ron Shepard

unread,
Dec 30, 2020, 3:50:05 AM12/30/20
to
On 12/29/20 6:22 PM, spectrum wrote:
> What I found interesting is that an assignment between
> two variables of the same type is allowed (maked as "L-1" in the code below),
> while their comparison is not allowed (marked as "L-2").

I think you need to define the == operator for the defined type. There
is no default or intrinsic meaning of == as there is for =.

> Does this mean that bitwise comparison does not work for such cases?

I'm not sure what this means. In fortran, intrinsic type entities are
compared by value, not by their bits, and user defined types are
compared however the programmer wants them to be. Thus issues regarding
padding or bounds information for unused dimensions, which might be
associated with undefined bits, never arises.

However, I'm not sure that the comparisons would work even then. The
compiler only sees them as CLASS(*). I think you need to put the
comparison code within SELECT TYPE blocks before the compiler sees them
as specific types rather than CLASS(*). Then the compiler will know
which == operator to invoke.

All that seems like a lot of programming effort, but I think that is the
only way to get the == operators to work correctly. Maybe someone knows
some object-oriented incantation to simplify that process?

$.02 -Ron Shepard



spectrum

unread,
Dec 30, 2020, 7:05:02 AM12/30/20
to
Hi Ron,

On Wednesday, December 30, 2020 at 5:50:05 PM UTC+9, Ron Shepard wrote:
> > Does this mean that bitwise comparison does not work for such cases?
> I'm not sure what this means. In fortran, intrinsic type entities are ... (snip)

I am sorry about my confusing post above, where I was thinking about
much simpler data structures that consist only of primitive data types
(like bind(C) derived types?). So please ignore the parts about bitwise stuff...

> However, I'm not sure that the comparisons would work even then. The
compiler only sees them as CLASS(*). I think you need to put the
comparison code within SELECT TYPE blocks before the compiler sees them
as specific types rather than CLASS(*). Then the compiler will know
which == operator to invoke.

My understanding of CLASS(*) is that the compiler has the knowledge of
the dynamic type of passed variables internally at run time, because we can use
SELECT TYPE for testing the dynamic type. Then, if each component has a comparison operator
already defined (via intrinsic types or user-defined ones), I imagined the compiler
may be able to compare each component internally (at run time)
and return some "overall" result as the value of obj1 == obj2.
But, if the component is an array, the comparison of the array components gives
an array of logical values, so the meaning of "overall" result (of the comparison)
is not clear... So, obj1 == obj2 (as values) may be far from trivial (if to be done
without user-defined ==), as compared to just the comparison of their addresses...

> All that seems like a lot of programming effort, but I think that is the
only way to get the == operators to work correctly. Maybe someone knows
some object-oriented incantation to simplify that process?

I would also like to know such a method, if available...

By the way, in my programs, I use derived types that represent energy
components (of the total system), and those energies are represented
as type components. Then, I often want to do something like

ene = ene * scale
or
ene_sum = ene_sum + ene_current

where "ene" is an object of a derived type having many energy components.
However, this is possible if we define operators, but the corresponding routines
need to be modified for each newly added component in "ene",
so I feel it is very error-prone (because I forget updating the routines...XD)
So, I am wondering if it is possible for Fortran
(in future) to apply various operators like * and + automatically in a component-wise way,
if there is no user-defined operators provided.
This is already possible for the assignment (like ene2 = ene1), but not available
for ene = ene * scale (for example).

# By the way, some languages seem to provide mechanisms for making it easier
to define such operators (e.g. by traversing all components via for-loop like things),
which seems very convenient.

Ev. Drikos

unread,
Dec 30, 2020, 12:17:35 PM12/30/20
to
Hello,

This example uses overloading to avoid large select type constructs:
https://gist.github.com/drikosev/477c26aa31543e1e7d14d67b0d6ba7c4

Admittedly, I don't know very well the (Fortran) language though.


Ev. Drikos

FortranFan

unread,
Dec 30, 2020, 12:59:11 PM12/30/20
to
On Wednesday, December 30, 2020 at 12:17:35 PM UTC-5, Ev. Drikos wrote:

> ..
> This example uses overloading to avoid large select type constructs: ..

There are some Fortran processors that will fail your very first check involving integers because with dummy arguments of "CLASS(*)", your comparison function will override the intrinsic operation as well.

I personally do not think that is appropriate, but the wording in the Fortran standard is unfortunately inadequate on this aspect. That is, different compiler implementors with backgrounds from different language locales globally will really struggle with the 'standardese' here and end up with different approaches, thereby deviating away from the very premise of the standard.

A formal interp on this is long overdue, I feel.

https://groups.google.com/g/comp.lang.fortran/c/Ke-8-fOzXFQ/m/RccwYYGKCAAJ

FortranFan

unread,
Dec 30, 2020, 1:19:40 PM12/30/20
to
On Wednesday, December 30, 2020 at 12:17:35 PM UTC-5, Ev. Drikos wrote:

>.. I don't know very well the (Fortran) language though.

For most Fortranners though, the *safer* approach will be rely on as much *compile-time* assistance and checking as possible, particularly in the case of OP.

They can then define a simple "super object" themselves a la Java and have all their derived types be subclasses thereof i.e., extend from such a base type.

Here's a modified example of your code that I think will work as expected with almost any Fortran compiler out there claiming to support Fortran 2003, 2008 facilities:
--- begin code ---
module base_m
! "super object"

type, abstract :: base_t
contains
private
procedure, pass(lhs) :: IsNotEqual
procedure(Icompare), pass(lhs), deferred, public :: IsEqual
generic, public :: operator(==) => IsEqual
end type base_t

abstract interface
function Icompare( lhs, rhs ) result(r)
import :: base_t
! Argument list
class(base_t), intent(in) :: lhs
class(base_t), intent(in) :: rhs
! Function result
logical :: r
end function
end interface

contains

function IsNotEqual( lhs, rhs ) result(r)

class(base_t), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r

r = .not.(lhs == rhs)

end function IsNotEqual

end module base_m

module m_type1

use base_m, only : base_t

type, extends(base_t) :: Type1
integer :: n1
contains
procedure :: IsEqual => eq1
end type


contains

function eq1( lhs, rhs) result(r)

class(Type1), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r

r = .false.
select type ( rhs )
type is ( Type1 )
r = ( lhs%n1 == rhs%n1 )
end select

end function eq1

end module m_type1

module m_type2

use base_m, only : base_t

type, extends(base_t) :: Type2
integer :: n2
contains
procedure :: IsEqual => eq2
end type


contains

function eq2( lhs, rhs) result(r)

class(Type2), intent(in) :: lhs
class(base_t), intent(in) :: rhs
logical :: r

r = .false.
select type ( rhs )
type is ( Type2 )
r = ( lhs%n2 == rhs%n2 )
end select

end function eq2

end module m_type2

program main

use base_m, only : base_t
use m_type1, only: Type1
use m_type2, only: Type2

class(base_t), allocatable :: a, b, c, d
class(base_t), allocatable :: apples, oranges

logical eq
integer :: i=2, j=2

a = Type1( n1 = 100 )
b = Type1( n1 = 100 )

c = Type2( n2 = 200 )
d = Type2( n2 = 200 )

print *, "----------------------------------------------------"

print *, "I'll Compare integers, I thought it should be equal:"
eq = i == j
print *, "MAIN PROGRAM: i == j is:", eq

print *, "I'll Compare Type1 Objects, I thought it should be equal:"
eq = a == b
print *, "MAIN PROGRAM: a == b is:", eq

print *, "I'll Compare Type2 Objects, I thought it should be equal:"
eq = c == d
print *, "MAIN PROGRAM: c == d is:", eq


apples = Type1( n1 = 100 )
oranges = Type2( n2 = 100 )

print *, "I'll Compare Apples & Oranges:"
eq = apples == oranges
print *, "MAIN PROGRAM: apples == oranges is:", eq

end
--- end code ---

Paul Richard Thomas

unread,
Dec 30, 2020, 1:32:17 PM12/30/20
to
For what it is worth, the programme below works back to at least gfortran-7.4.1. Depending on the version, valgrind detects various invalid reads and memory leaks with the intrinsic type assignments. ifort 2021.1 Beta 20201112 dies at runtime with some rather horrible looking stack problem. I will post a report.

Paul

! Answer in http://computer-programming-forum.com/49-fortran/0d8b0fdf665f09b9.htm
! used as starting point for == operator for unlimited polymorphic entities.
!
MODULE types
IMPLICIT none
public :: operator (==)
TYPE t1
character(len=8) :: chr
integer :: i
end TYPE t1

TYPE t2
character(len=8) :: chr
integer :: i
end TYPE t2

interface operator (==)
module procedure star_eq
end interface

contains
function star_eq(a,b)
implicit none
class(*), intent(in) ::a,b
logical ::star_eq
star_eq = same_type_as (a, b)
if (.not. star_eq) return
select type (a)
! TYPE T1
type is (t1)
select type (b)
type is (t1)
star_eq = (a%chr .eq. b%chr) .and. (a%i .eq. b%i)
end select
! TYPE T2
type is (t2)
select type (b)
type is (t2)
star_eq = (a%chr .eq. b%chr) .and. (a%i .eq. b%i)
end select
! REAL(KIND=4)
type is (real(kind = 4))
select type (b)
type is (real(kind = 4))
star_eq = (a .eq. b)
end select
! CHARACTER(KIND=1)
type is (character(*))
select type (b)
type is (character(*))
star_eq = (a .eq. b)
end select
end select
end function star_eq
end MODULE types

program test_eq
use types
implicit none
class(*), allocatable :: x, y

x = t1('a', 1)
y = t1('a', 1)
if (.not. (x == y)) stop 1
x = t1('a', 1)
y = t1('b', 1)
if (x == y) stop 2
x = t1('a', 1)
y = t1('a', 2)
if (x == y) stop 3
x = t1('a', 1)
y = t2('b', 2)
if (x == y) stop 4
x = t2('c', 3)
y = t2('c', 3)
if (.not. (x == y)) stop 5
y = 1.0_4
if (x == y) stop 6
x = 1.0_4
if (.not. (x == y)) stop 7
x = 2.0_4
if (x == y) stop 8
x = "Mary had a little lamb"
y = "whose fleece was as white as gold"
if (x == y) stop 9
y = "Mary had a little lamb"
if (.not. (x == y)) stop 10
deallocate (x, y)
end program test_eq


Ev. Drikos

unread,
Dec 30, 2020, 2:27:02 PM12/30/20
to
On 30/12/2020 20:19, FortranFan wrote:
> For most Fortranners though, the*safer* approach will be rely on as much*compile-time* assistance and checking as possible, particularly in the case of OP.
>
Without any doubt, static type checking is of course much safer
but the original question was how I define this:

> logical function compare_star (a, b)
> class(*), intent(in) :: a, b


> They can then define a simple "super object" themselves a la Java and have all their derived types be subclasses thereof i.e., extend from such a base type.
> Here's a modified example of your code that I think will work as expected with almost any Fortran compiler out there claiming to support Fortran 2003, 2008 facilities:

The important feature in my example, which of course may not be
acceptable by the OP, because he doesn't want ie subclassing in
this case, is that it avoids large select type constructs.

The justification is that one would normally opt to avoid changes in the
base class each time a new subclass is added (we've discussed it again
in the past).

Admittedly, I wasn't aware that a '==' with a "class(*)" may override
the intrinsic types, so I removed the two I had (integer & real). If I
add them it might be more portable.

Thanks for your example. I'll need my time to study it.

Ev. Drikos

GianLuigi Piacentini

unread,
Dec 30, 2020, 4:58:17 PM12/30/20
to
On 30/12/20 19:19, FortranFan wrote:
> On Wednesday, December 30, 2020 at 12:17:35 PM UTC-5, Ev. Drikos wrote:
>
>> .. I don't know very well the (Fortran) language though.
>
> For most Fortranners though, the *safer* approach will be rely on as much *compile-time* assistance and checking as possible, particularly in the case of OP.

Hi all,
I generated an interesting discussion!

My point is, I am inside a container. Storing class(*) items seems the
quickest approach, at the expense of a select type construct whenever
retrieving stored items (basically, only when retrieving item value).
But, when trying to search inside the container, it would be nice to
compare _without_knowing_the_type_ (the container should be type-agnostic).
Something like this pseudocode
logical function compare_star (a, b)
class(*), intent(in) :: a, b
compare_star = same_type (a, b) .and. &
some_form_of_bit_by_bit_comparison(a,b)

It should be enough, because we already know by the same_type that the 2
items are of the same dynamic type, and so should be comparable.

Otherwise, I think I will have to resort to some form of reverse
communication. A little involved, would like to avoid it, if possible.

Thanks
Gigi

Ev. Drikos

unread,
Dec 30, 2020, 5:43:04 PM12/30/20
to
On 30/12/2020 23:58, GianLuigi Piacentini wrote:

> My point is, I am inside a container...
> ...
> Something like this pseudocode
> logical function compare_star (a, b)
>   class(*), intent(in) :: a, b
>   compare_star = same_type (a, b) .and.  &
> some_form_of_bit_by_bit_comparison(a,b)
>

The chances are you need:

integer function compare_star (a, b)
class(*), intent(in) :: a, b

Returning:

0: when a == b, otherwise
-1: a < b
1: a > b

FortranFan

unread,
Dec 30, 2020, 5:52:00 PM12/30/20
to
On Wednesday, December 30, 2020 at 4:58:17 PM UTC-5, GianLuigi Piacentini wrote:

> ..
> My point is, I am inside a container. Storing class(*) items seems the
> quickest approach, at the expense of a select type construct whenever
> retrieving stored items (basically, only when retrieving item value).
> But, when trying to search inside the container, it would be nice to
> compare _without_knowing_the_type_ (the container should be type-agnostic). ..

Toward a "container", what would technically help is Generics. But current Fortran standard is deficient when it comes to Generics. Trying to use unlimited polymorphism with 'class(*)' as a poor man's substitute for Generics is more trouble than it's worth.

With current Fortran standard, there are basically 3 options:

1) consider instead a poor man's approach for the container itself which is that the container is constrained to what it can support e.g., any intrinsic type PLUS any derived types that extend from a particular abstract type like the 'base_t' I show above. That way, all the intrinsic facilities with comparison operation work for all the intrinsic types and also the defined operations as required by that abstract type design that invoked for the derived types. So then the dummy arguments with such operators are 'class(base_t)' instead of 'class(*)' and the intrinsic operations are left untainted. This is as I show with the modified example of @Ev. Drikos.

2) resort to macro-driven programming to emulate templates using a preprocessor e.g., 'fypp' https://fypp.readthedocs.io/en/stable/fypp.html,

3) Use interoperability facility with C to work with containers in a mixed-language solution e.g., 'qcontainers' https://groups.google.com/g/comp.lang.fortran/c/PQMk4b_A8Ak/m/p-V4pkv8BAAJ or with C++ STL, etc.

Paul Richard Thomas

unread,
Jan 3, 2021, 12:00:47 PM1/3/21
to
On Wednesday, 30 December 2020 at 18:32:17 UTC, Paul Richard Thomas wrote:
> For what it is worth, the programme below works back to at least gfortran-7.4.1. Depending on the version, valgrind detects various invalid reads and memory leaks with the intrinsic type assignments. ifort 2021.1 Beta 20201112 dies at runtime with some rather horrible looking stack problem. I will post a report.

This comes about because of a difference of interpretation in the following part of the standard between gfortran on one hand and ifort/NAG on the other:
15.4.3.4.2p1 (Defined operation) says:
"If the operator is an intrinsic-operator (R608), the number of dummy
arguments shall be consistent with the intrinsic uses of that operator,
and the types, kind type parameters, or ranks of the dummy arguments
shall differ from those required for the intrinsic operation (10.1.5)."

An interpretation request has been drafted by Steve Lionel (thanks!). It is gcc problem report 98498. A patch for gfortran is posted there, which aligns gfortran with the other two compilers.

Regards

Paul

dave_th...@comcast.net

unread,
Jan 31, 2021, 4:03:41 PM1/31/21
to
On Tue, 29 Dec 2020 08:37:11 +0200, "Ev. Drikos" <drik...@gmail.com>
wrote:

> On 29/12/2020 06:29, gah4 wrote:
[snip]
> > In Java, if you compare two variables, you would actually compare the
> > references to them. (Pointers in other languages).
> >
> So far, so good.
>
> > Many classes have a equals() method that will compare two instances
> > of a class. Otherwise, there is no way for the system to know what you mean
> > by compare.
>
> To work ie with containers, the interface Comparable is also available.
>
> In Java the class Object is a super-class of all other classes (apart
> the primitive types, ie int, boolean, ...) that implements the interface
> Comparable. So, each subclass can declare that implements the interface
> and provide the method compareTo.
>
No, Object doesn't implement Comparable. _Some_ subclasses do, and as
you say they must implement compareTo() since the interface doesn't.
(In original Java interfaces could not provide any implementations;
since 8 they can, but most of the library and type hierarchy was
designed before 8.)

> Various containers, like TreeMap or TreeSet ie, can then keep instances
> of such classes in an organized manner. This works without templates.
>
Only the ones that implement Comparable. Note the java.util
containers, and many other things in the library, do use generics to
enforce type correctness at compile time since (1.)5; although runtime
checks also still occur they now should usually be redundant.

java.lang.Object does implement equals() as reference-equals, so that
is the default for all subclasses (which means all user classes) that
don't override it; many do override it to compare contents. Object
also implements hashCode() as based (only) on the reference; this
allows you to produce a deterministic (within one JVM) and consistent
(i.e. total) order but one that is typically not meaningful or useful.

Ev. Drikos

unread,
Jan 31, 2021, 6:56:32 PM1/31/21
to
On 31/01/2021 23:03, dave_th...@comcast.net wrote:
> On Tue, 29 Dec 2020 08:37:11 +0200, "Ev. Drikos" <drik...@gmail.com>
> wrote:
>
>> ....
>>
>> In Java the class Object is a super-class of all other classes (apart
>> the primitive types, ie int, boolean, ...) that implements the interface
>> Comparable. So, each subclass can declare that implements the interface
>> and provide the method compareTo.
>>
> No, Object doesn't implement Comparable. _Some_ subclasses do, and as
> you say they must implement compareTo() since the interface doesn't.

Maybe, I don't remember perfectly all the details. Clearly, I was forced
to add some (interface) methods after a JDK upgrade in a class that was
likely active, not as ie with the code below that presents only some
runtime errors. Yet, I haven't kept a ChangeLog for that project!

In case I recall more details, I'll come back to this thread. Your
comment seems to be justified.


Ev. Drikos



-----------------------------------------------------------------------

$ ecj -1.5 comparable.java
$ javac comparable.java
$ gcj --main=comparable comparable.java
$ ./a.out
list
Exception in thread "main" java.lang.ClassCastException: comparable
cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(libgcj.14.dylib)
at java.util.TreeMap.put(libgcj.14.dylib)
at java.util.TreeSet.add(libgcj.14.dylib)
at comparable.main(a.out)


---------------------------------------------------------------------
$ cat comparable.java

class comparable extends java.lang.Object {
Integer i;
comparable(int i) {
this.i = new Integer(i);
}

public static void main(String args[]) {
System.out.println("list");

java.util.TreeSet<comparable> ts = new java.util.TreeSet<comparable>();
ts.add(new comparable(1));
ts.add(new comparable(2));
ts.add(new comparable(3));

java.util.Iterator<comparable> itr = ts.iterator();

while ( itr.hasNext() ) {
Object obj = itr.next();
System.out.println(obj);
}
System.exit(0);
}
0 new messages