Topic: STL operators != > <= >=


Author: martelli@cadlab.cadlab.it (Alex Martelli)
Date: 1995/09/04
Raw View
ncm@netcom.com (Nathan Myers) writes:
 ...
>> have iostream.h, but iostream.hpp.  (At least, that is what Zorland had;
>> when I last looked, they were the only C++ compiler available under
>> MS-DOS:-).)
 ...
>"Zorland"?  :-)

Yes, "Zorland"; they later changed name to "Zortech", and later still,
I think, were acquired by Symantec.  They never were the only supplier
of a C++ implementation under MS-DOS, because cfront-based ones were
around before them; but as for "native implementation", I do think so.


Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it                            Phone: ++39 (51) 6130360
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia   Fax: ++39 (51) 6130294
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/25
Raw View
Nathan Myers (ncm@netcom.com) wrote:
|> Distribution:
|> In article <41htgo$35v@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
|> >Nathan Myers (ncm@netcom.com) wrote:

|> >|> #include <iostream.h>
|> >
|> >|> ... is equivalent to:
|> >
|> >|> #include <iostream>
|> >|> using std::basic_iostream;
|> >|> using std::cout;
|> >|> ...
|> >
|> >Where does it say this in the draft standard?

|> My apologies, I should have used <stdio.h> and <cstdio> in the
|> example.  <iostream.h> will be a universally-implemented vendor
|> extension, implemented with semantics equivalent to above.

We hope:-).

What about the MS-DOS based machines?  Last time I looked, they didn't
have iostream.h, but iostream.hpp.  (At least, that is what Zorland had;
when I last looked, they were the only C++ compiler available under
MS-DOS:-).)
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ncm@netcom.com (Nathan Myers)
Date: 1995/08/28
Raw View
Distribution:
In article <41kf36$1ut@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
> Nathan Myers (ncm@netcom.com) wrote:
> |> ...  <iostream.h> will be a universally-implemented vendor
> |> extension, implemented with semantics equivalent to above.
>
> We hope:-).
>
> What about the MS-DOS based machines?  Last time I looked, they didn't
> have iostream.h, but iostream.hpp.  (At least, that is what Zorland had;
> when I last looked, they were the only C++ compiler available under
> MS-DOS:-).)

My apologies, again.  <iostream.h>, or <iostream.hpp>, or <iostream.h++>,
or <iostream.H>, or <iostream.hxx>, or <iostream.hh>, will be a
universally-implemented extension.  Which name is chosen will of
course be up to the vendor.  For portability, code to the standard.

"Zorland"?  :-)

Nathan Myers
myersn@roguewave.com


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/29
Raw View
Nathan Myers (ncm@netcom.com) wrote:
|> Distribution:
|> In article <41kf36$1ut@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
|> > What about the MS-DOS based machines?  Last time I looked, they didn't
|> > have iostream.h, but iostream.hpp.  (At least, that is what Zorland had;
|> > when I last looked, they were the only C++ compiler available under
|> > MS-DOS:-).)

|> "Zorland"?  :-)

Shows how long I haven't looked at MS-DOS.  It was, of course, Zortech.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fec1104@comune.bologna.it (fec1104)
Date: 1995/08/30
Raw View
Distribution:
In article <41kf36$1ut@gabi.gabi-soft.fr>, kanze@gabi-soft.fr says...

>What about the MS-DOS based machines?  Last time I looked, they didn't
>have iostream.h, but iostream.hpp.  (At least, that is what Zorland had;
>when I last looked, they were the only C++ compiler available under
>MS-DOS:-).)

There are several good compilers. Symantec 7.00 and Watcom 10.0 are quite
good. I' m usign SC 7.0 and I' m quite satistfied. It offers a good
exception handling implementation and compiles well most of the
ObjectSpace STL examples. You can find an extensive review on the July
issue of the C++ Report.



---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/20
Raw View
Distribution:
In article <MATT.95Aug16101930@physics2.Berkeley.EDU>,
Joe Buck <jbuck@Synopsys.COM> wrote:
>Distribution:
>maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>> The STL definitions were in fact quite wrong and
>>completely unnacceptable until overloading of function templates by
>>partial specialisation was introduced into the C++ language.
>>
>> Now the definitions in STL remain wrong, but they are
>>only defaults which can be overriden.
>
>Not true; you can't change the return type (so that, for example,
>< on two arrays of reals returns an array of bools as in APL).

 Not true. You CAN.  The return type of a
FUNCTION TEMPLATE is part of it's signature. (Unlike ordinary
functions!)

 Lets be clear: we're talking about OVERLOADING and
NOT specialisation.  You CAN'T specialise a function template
as I understand it.

 The "specialisation" rules for functions are rules
of overload resolution. For example:

 template<class T, class U> void f(T,U); //#1
 template<class T, class U> int f(T,U);  //#2
 template<class T, class U> int f(U,T);  //#3
 template<class T> T f(T,T);             //#4
 f(1,1); // FINE! #4
 f<float,int>(1, 1.0); // FINE! #3 is best match

These are distinct templates.  The first 3 would always
be ambiguous if used without explicit parameter binding.


 template<class T> class APLarray { .. };
 template<class T> APLarray<bool>
 operator == (APLarray<T> const&, APLarray<T> const&);
 template<class T> APLarray<bool>
 operator != (APLarray<T> const&, APLarray<T> const&);

is perfectly OK in the presence of the STL globals.
Note the container would NOT be STL compliant.

In fact:

 template<class T> T operator != (T const&,T const&);

is perfectly viable too because the return type is different.
(Use would be ambiguous with STL != in reach as well, however)

[BTW: I was surprised at this resolution myself. I'd not have
made the return type part of the signature]

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ncm@netcom.com (Nathan Myers)
Date: 1995/08/25
Raw View
Distribution:
In article <41htgo$35v@gabi.gabi-soft.fr>, J. Kanze <kanze@gabi-soft.fr> wrote:
>Nathan Myers (ncm@netcom.com) wrote:

>|> #include <iostream.h>
>
>|> ... is equivalent to:
>
>|> #include <iostream>
>|> using std::basic_iostream;
>|> using std::cout;
>|> ...
>
>Where does it say this in the draft standard?

My apologies, I should have used <stdio.h> and <cstdio> in the
example.  <iostream.h> will be a universally-implemented vendor
extension, implemented with semantics equivalent to above.

Nathan


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: mfinney@inmind.com
Date: 1995/08/10
Raw View
In <40cbmh$liu@lyman.pppl.gov>, Etay Bogner <Etay_Bogner@mail.stil.scitex.com> writes:
>mfinney@inmind.com wrote:
>Its trivial that the "conflict will not occur unless both namespaces have a local using". I'm saying that
>its also trivial to solve the ambiguity.

I understood your example.  But it would require introducing a dependency into
the order of declaration.  Which has been found to be a "bad thing" in the past.
I do NOT agree that N1::f() is the correct result -- I agree with the draft standard
here.  My only problem is that the draft standard should NOT be defining MY
operators -- and incorrectly at that!

Michael Lee Finney







Author: fenster@cs.columbia.edu (Sam Fenster)
Date: 1995/08/11
Raw View
> mfinney@inmind.com wrote:
>> The problem is not defined < in terms of > or vice versa, but defined <= in
>> terms of >.  In a linear order there are three possibilities, a < b, a = b
>> or a > b.  In a partial order there are four possibilities, a < b, a = b,
>> a > b or a >< b (using operator >< () mean "not comparable).
>>
>> For a linear order, a <= b is equivalent to not (a > b).  However, that
>> fails to be true for a partial order because there is an extra possiblity.

Mike Chapman <mchapman@synopsys.com> writes:
> I disagree. If a and b are not ordered (ie not comparable), it is an error
> to try to compare them. Hence a < b (or any of the other 5 operators) are
> free to do whatever they like - throw an exception, return a random value or
> start up a game of tetris.

Wrong.  It is *not* an error to try to compare them.  "Not comparable" just
means that a<b, a==b and a>b are all false.  mfinney has merely defined a new
(non-C++) operator >< that is defined to be true exactly when the other three
are false.  Think of a datatype for which < means, "is an ancestor of."  Or
"is a subset of."

And he's saying that because the STL headers give a template operator > that
(for any type) returns true when <= is false, it screws up comparisons for any
data type that is partially, but not totally (linearly) ordered!






Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/11
Raw View
You did NOT understand.

The reason N1::f() should be choosen is because it's in the SAME namespace
as N1:g(), and NOT because it was declared before N2:f().

That's why I gave the paralel "global function versus member function" name
resolution example.

The Examples AGAIN ( somewhat re-ordered for clarity ) :

namespace N1 { // re-ordered for clarity
        void g();
        };

namespace N2 {
        void f();
        };

namespace N1 { // moved here for clarity
        void f();
        };


using namespace N1;
using namespace N2;

void N1::g() {
        f(); // here is the BUG in the language. Should use N1::f(). See
Below.
        }

The paralel "global function versus member function" name resolution :

void f();

class X {
        void f();
        void g();
        };

void X::g() {
        f(); // here it's OK. calls X::f() and NOT ::f()
        }

Just think of a namespace as a class declaration.

In the second example, X::f() is choosen simply because it's in the SAME
scope as X::g().

So why not do so for namespaces ?

I think this is a logical solution to the problem of name resolution between
namespaces. It does NOT intreduce new problems, since we already know that
the same name resolution method is used with global functions and classes,
as shown in the second example.

Since, for instance, only one "void f()" can exists in a namespace ( as in a
class ), the language can choose N1::f() simply because it's in the SAME
namespace as the calling function, N1:g(), and can make a "bad thing" since
the rules are clear ( and already working ).

And again, this is EXACTLY what happens in the second example, X::f() is
choosen simply because it's in the SAME name scope as the calling function,
in this case X::g().

This will solve the problem of defining the template operator <,>,!= etc.
functions if the classes that USES your classes will be in the SAME
namespace as your classes, thus the calls for those template function will
resolve to YOUR functions, instead of STL's, and this is simply ( everything
is simple here ? ) because they are in the SAME namespace as your templates.

HTH,

Will someone send this proposed correction to the draft to the standard
committe ?

-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.








Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/11
Raw View
So you didn't understand.

I mean that N1::f() should be choosen just because it's in the SAME
namespace as N1::g().

The declaration order have NOTHING to do with my solution.

That's why I gave the global function versus the member function
example.

-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.



--
Steve Clamage, stephen.clamage@eng.sun.com





Author: mfinney@inmind.com
Date: 1995/08/11
Raw View
In <40ebdo$5on@lyman.pppl.gov>, Etay Bogner <Etay_Bogner@mail.stil.scitex.com> writes:
>You did NOT understand.

You are correct, I did not understand initially -- I should have read a bit closer.
Your point is a good one, and if I had to guess without knowing, I would have
assumed that it worked the way you want based (obviously) on the fact that
class namespaces work that way -- and namespaces are conceptually just an
extension of class namespaces.

As far as fixing my problem is concerned, it would ONLY do so in the development
of the class library itself.  Eventually its users (hopefully many) will face the same
problem and your solution will NOT work for them.

Michael Lee Finney







Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/14
Raw View
In article <408o8u$c0p@hermes.synopsys.com>,
Mike Chapman  <mchapman@synopsys.com> wrote:
>mfinney@inmind.com wrote:
[ snip snip ]

>>This is why the definitions are wrong.
>>
>
>I disagree. If a and b are not ordered (ie not comparable), it is an
>error to try to compare them. Hence a < b (or any of the other 5 operators)
>are free to do whatever they like - throw an exception, return a random
>value or start up a game of tetris.

 This is an unacceptably severe overconstraint.
I see nothing wrong with a mathematical SET class with < meaning
subset. This relation is a partial order, but "subset" is well defined
for ALL pairs sets.

 The fact is that < is mathematically well defined on
pointers because they are naturally partially ordered -- but the
ISO C Standard does not require correct computation of this
function for no-comparable operands, and neither does STL.

 The STL definitions were in fact quite wrong and
completely unnacceptable until overloading of function templates by
partial specialisation was introduced into the C++ language.

 Now the definitions in STL remain wrong, but they are
only defaults which can be overriden.

 I personally do NOT like this arrangement (and have
deleted the templates from my copy of STL). I'd prefer a mechanism like:

 class X : total_order ....
 class Y : partial_order

with the default being to issue a diagnostic for an undefined function.
A default, however, is tolerable.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189






Author: mfinney@inmind.com
Date: 1995/08/15
Raw View
Distribution:

In <407les$fjs@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>In article <3vqnqf$kst@hardcopy.ny.jpmorgan.com>,
>Joe Borkoles  <jborkole@jpmorgan.com> wrote:
> I simply deleted the templates from the STL files.
>No part of the HP STL implementation I have used so far uses
>these templates -- but I may have missed something.

The draft standard does not require that headers be files or
editable in any way.  Not to mention that is a constance pain
in the maintenance area.

> I dislike the defaulting to the total order

The problem is that such defaulting is only done for "convenience".  To
avoid requiring the other operators to be defined by providing a default
implmentation -- that unfortunately can conflict with other implementations.
It is not even that much of a convenience.

> , but C++
>doesn't contain sufficient functionality to declare, on a class
>by class basis, that some members (friends) should be defined based on
>a model. Macros still remain the simplest way to do this. :-(
>Global defaults is a very second rate solution, but arguably
>better than macros :-)

I don't see where this is a problem solved by templates vs. macros
at all.  It is not a weakness in the template system, merely an
incorrect semantic assumption on the parts of the authors of STL.

Michael Lee Finney


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1995/08/15
Raw View
fenster@cs.columbia.edu (Sam Fenster) writes:
>And he's saying that because the STL headers give a template operator > that
>(for any type) returns true when <= is false, it screws up comparisons for any
>data type that is partially, but not totally (linearly) ordered!

No, because the STL template definition of > is merely a default, which
can be overridden with a specialized template for the class in question.

The real bug is that you can't change the return type in a specialization;
what STL is requiring is that relational operators always return bool.



--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Anagrams for "information superhighway": Enormous hairy pig with fan
A rough whimper of insanity
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/15
Raw View
You did NOT understand it.

There is NO "dependency into the order of declaration".

The reason that the language should choose N1::f() is that it's in the SAME namespace
as N1::g(), and NOT because it's decalred BEFORE N2::f().

That's why I compared it to the "global function versus member function" function
resolution.

AGAIN, the example ( but re-ordered ):

namespace N1 {
void g();
};

namespace N2 {
void f();
};

namespace N1 {
void f();
};

using namespace N1;
using namespace N2;

void N1::g() {
f(); // here is the BUG in the language. should use N1::f().see below.
}

And AGAIN, The paralel "global function versus member function" example :

void f();

class X {
void f();
void g();
};

void X::g() {
f(); // here it's OK. calls X::f() and NOT ::f()
}

Think of a namespace as a class, and it will all be clear.

The implementation of namespaces, BTW, is exactly this, from the point of view of
name resolution ( I know that's it's NOT exactly the same, so please don't say
anything :-) ).

A SHORT explanation :

A namespace can't have two, for instance, "void f()", even in differant source files
( the linker will shout ). This is the same for classes ( in my example, class X ).
So there is NO way to make a WRONG choise. Either choose the function in your own
namespace OR try to choose another function in another namespace.

So the language can CHOOSE to use N1::f() over N2::f() simply because THEY BOTH ARE
IN THE SAME NAMESPACE. This is ALREADY done in classes, in X::g() the choosen
function is X::f() and NOT ::f(), simply because X::g() and X::f() are in the same
SCOPE ( I'm repeating myself :-) ).

This WILL solve your problem of the template operator function, if ALL the USERS of
your code will be in the SAME namespace as your CODE ( which is NOT a hard
requirment. better than others, anyway ), and the language will CHOOSE your templates
OVER STL's, SIMPLY because they are in the SAME namespace.

HTH.

Is there somebody willing to send this correction to the draft to the standrad
committe ?

-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ncm@netcom.com (Nathan Myers)
Date: 1995/08/15
Raw View
It's not unreasonable to delete the templates for operators >= etc.
from your copy of STL, until you get a compiler that implements
namespaces and the new lookup rules properly.  (i.e. I would.)

I have seen some incorrect statements posted on this thread.

#include <iostream.h>

is *not* equivalent to:

#include <iostream>
using namespace std;

It is equivalent to:

#include <iostream>
using std::basic_iostream;
using std::cout;
...

This is important.  "using namespace" is to be used only
in a most restricted way.  Normally, you'll say "using std::foo"
if you use foo a lot.  You will say "using namespace std" only
in another namespace you control, usually a block.  Anybody
who puts "using namespace std" in a header file outside any
namespace is being a bad citizen indeed.

Nathan Myers
myerns@roguewave.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/15
Raw View
There is NO restriction on where and when one can add "stuff" to
namespaces.

Althought my solution is NOT perfect, it does solve the problem. The
users of your class library should declare their code in the same
namespace as your library.

Again, this is NOT perfect, but is quite simple.

There is even some logic in it, since your code is somewhat special, in
a way that defines a SEPERATE "mathematical" space ( partial order ), so
there is some logic in putting all the "partial order" code in a unique
namespace, to be used both by the library and the users of the library.

-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1995/08/16
Raw View
Distribution:
maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
> The STL definitions were in fact quite wrong and
>completely unnacceptable until overloading of function templates by
>partial specialisation was introduced into the C++ language.
>
> Now the definitions in STL remain wrong, but they are
>only defaults which can be overriden.

Not true; you can't change the return type (so that, for example,
< on two arrays of reals returns an array of bools as in APL).
--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Anagrams for "information superhighway": Enormous hairy pig with fan
      A rough whimper of insanity

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/08
Raw View
In article <3vqnqf$kst@hardcopy.ny.jpmorgan.com>,
Joe Borkoles  <jborkole@jpmorgan.com> wrote:
>mfinney@inmind.com wrote:
>>In the 28 April 1995 Draft Standard (which I was only able to download last week)
>>section 20.2.1 says that the STL portion of the Standard Library will define
>>operator!=(), operator>(), operator<=() and operator>=() in terms of operator=()
>>and operator<().
>>
>>This breaks my code!  And NOT in a fixable fashion!
>>
>
>I too have been finding these operators quite annoying and forcing me to reorder my
>header files in a most unpleasant fashion. I have had some discussion with
>colleagues and we thought that breaking up the standard library into
>hierarchical namespaces might be the way to go.

 I simply deleted the templates from the STL files.
No part of the HP STL implementation I have used so far uses
these templates -- but I may have missed something.

 This won't be necessary with an ISO Standard C++
compiler because of several new rules on lookup and overloading.

 I dislike the defaulting to the total order, but C++
doesn't contain sufficient functionality to declare, on a class
by class basis, that some members (friends) should be defined based on
a model. Macros still remain the simplest way to do this. :-(
Global defaults is a very second rate solution, but arguably
better than macros :-)


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: Mike Chapman <mchapman@synopsys.com>
Date: 1995/08/08
Raw View
mfinney@inmind.com wrote:
[ snip snip ]
>
>The problem is not defined < in terms of > or vice versa, but defined <= in
>terms of >.  In a linear order there are three possibilities, a < b, a = b or a > b.
>In a partial order there are four possibilities, a < b, a = b, a > b or a >< b (using
>operator >< () mean "not comparable).
>
>For a linear order, a <= b is equivalent to not (a > b).  However, that fails to
>be true for a partial order because there is an extra possiblity.
>
>If <= were defined in terms of > (or >= in terms of <) for IEEE floating point
>then even there there would be a problem because there are NaNs (not a number)
>objects in IEEE floating point which are not comparable to anything else,
>including other NaNs.
>
>This is why the definitions are wrong.
>

I disagree. If a and b are not ordered (ie not comparable), it is an
error to try to compare them. Hence a < b (or any of the other 5 operators)
are free to do whatever they like - throw an exception, return a random
value or start up a game of tetris.

--
Mike Chapman, Munich
   Some programming languages manage to absorb change,
   but withstand progress.
       -- Epigrams in Programming, ACM SIGPLAN Sept. 1982
.................................................................
.................................................................
.................................................................
.................................................................
(For the benefit of my brain dead news host.)






Author: jbuck@synopsys.com (Joe Buck)
Date: 1995/08/09
Raw View
matt@physics.berkeley.edu writes:
>Maybe I'm missing something, but I don't see anything in the standard
>that's in need of correction.  Yes, there's a template definition of
>other comparison operators in terms of operator< and operator==, and
>yes, that definition is incorrect for some types.  But isn't that what
>template specialization is for?

In the APL language, the "<" operator, when used with two arrays of
matching size, returns an array of boolean values, not a single bool
(the results of comparisons on corresponding elements).  Similarly
for other relational operators.  The STL template declaration gives
*every* class type a set of relational operators that return bool.

This is a conflict that can only be worked around by never using any
STL header in code that implements or uses an "APLarray" class.
The STL approach basically mandates that the relational operators
*always* return bool, even for user-defined classes.  Now perhaps that
is reasonable, but it is a decision that should be thought about just
a bit.



--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Anagrams for "information superhighway": Enormous hairy pig with fan
      A rough whimper of insanity





Author: mfinney@inmind.com
Date: 1995/08/09
Raw View
In <407n9d$nb7@lyman.pppl.gov>, Etay Bogner <Etay_Bogner@mail.stil.scitex.com> writes:
>Wouldn't the use of name spaces solve your problem ?
>
>Another overhead is to wait for a compiler which implements namespaces :-).

The main problem is that far too much code will require a "using namespace std;"
along with my class libraries -- and then we get the conflict again.  Alternatively,
either the standard namespace or my namespace or both will have to be explicitly
qualified for ALL uses.  This is a VERY large disadvantage.  You want to be able
to use STL and other features of the C++ library "naturally", so you will almost
always have a "using namespace std;" in effect.

Also, of course, your second point is very true -- I am using the IBM VisualAge++
C++ compiler and they decided to go for other features rather than the latest
draft standard on the latest release due to user requests (only a couple of us
wanted things like RTTI and namespaces as opposed to "direct to som" compiling.
Further, the NT beta of the same compiler will be in process until early next
year, so the odds are that it will be a couple of years before the draft standard
(by then, hopefully the standard) is fully implemented.

I could use other compilers -- but they all have their advantages and
disadvantages.  The Borland OS/2 compiler is a joke -- it hasn't compiled
my code in years without too many compiler bugs to be worth tracking down.
Especially since they almost never release a fix without making it a new
release.  At least IBM comes out with an accumulative CSD every couple
of months.  There are some others, but most of there are twice as expensive
so I will have to live without RTTI and namespaces.

However, when they ARE implemented, my code will break if the STL
operator templates are not removed.  It could be argued that my code
should be "fixed", but the problem is that the STL code is "wrong" in
that it makes invalid semantic assumptions about those operators.  So
better to speak up now with some slim chance of getting the problem
fixed than be constantly trying to "patch" the compiler header files
(assuming, of course, that they can be edited -- which the standard
does NOT require).

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/09
Raw View
In <407les$fjs@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>In article <3vqnqf$kst@hardcopy.ny.jpmorgan.com>,
>Joe Borkoles  <jborkole@jpmorgan.com> wrote:
> I simply deleted the templates from the STL files.
>No part of the HP STL implementation I have used so far uses
>these templates -- but I may have missed something.

The draft standard does not require that headers be files or
editable in any way.  Not to mention that is a constance pain
in the maintenance area.

> I dislike the defaulting to the total order

The problem is that such defaulting is only done for "convenience".  To
avoid requiring the other operators to be defined by providing a default
implmentation -- that unfortunately can conflict with other implementations.
It is not even that much of a convenience.

> , but C++
>doesn't contain sufficient functionality to declare, on a class
>by class basis, that some members (friends) should be defined based on
>a model. Macros still remain the simplest way to do this. :-(
>Global defaults is a very second rate solution, but arguably
>better than macros :-)

I don't see where this is a problem solved by templates vs. macros
at all.  It is not a weakness in the template system, merely an
incorrect semantic assumption on the parts of the authors of STL.

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/09
Raw View
In <408o8u$c0p@hermes.synopsys.com>, Mike Chapman <mchapman@synopsys.com> writes:
>mfinney@inmind.com wrote:
>I disagree. If a and b are not ordered (ie not comparable), it is an
>error to try to compare them. Hence a < b (or any of the other 5 operators)
>are free to do whatever they like - throw an exception, return a random
>value or start up a game of tetris.

Tell that to the  committee that developed the IEEE floating point standard.  It
is NOT considered an error to compare a NaN and, say, 1.0 -- the result is
neither <, = nor >.  It is unordered.  If I have four possiblities for an ordering
relation (as I do for a partial order), then I have four relations defined.  Exactly
one of those is true for any two objects and the other three are false.  C++ does
not define a native "unordered" operator (but it should, for IEEE floating
point, if nothing else).  So if I ask (a < b) and they are unordered then the
result is false.  If a is equal to b then the  result is false.  No difference (logically).

It is only an error to compare to objects if they intrinsically cannot be compared.
But if they are merely unordered it is not an error.

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/09
Raw View
In <40958l$gqc@hermes.synopsys.com>, jbuck@synopsys.com (Joe Buck) writes:
>matt@physics.berkeley.edu writes:
>This is a conflict that can only be worked around by never using any
>STL header in code that implements or uses an "APLarray" class.

Not possible if you use any header at all.  The draft standard says that
it is undefined which headers any particular header include, but it is
legal for any header to include ALL headers.  I do NOT consider this
to be unreasonable, but it means that you cannot selectively avoid
parts of the standard library -- it is absolutely all or nothing.

Michael Lee Finney






Author: ark@research.att.com (Andrew Koenig)
Date: 1995/08/09
Raw View
In article <409bjt$59c@mujibur.inmind.com> mfinney@inmind.com writes:

> >Another overhead is to wait for a compiler which implements namespaces :-).

> The main problem is that far too much code will require a "using namespace std;"
> along with my class libraries -- and then we get the conflict again.

Why do you think so?
--
    --Andrew Koenig
      ark@research.att.com





Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/09
Raw View
The problem might be the overloading rules BETWEEN namespaces.
If I remember correctly, the following example produces an error :

namespace N1 {
 void f();
 void g();
 };

namespace N2 {
 void f();
 };

using namespace N1;
using namespace N2;

void N1::g() {
 f(); // here is the catch ( error )
 }

I think that the draft says that the call of "f" in N1::g() is ambiguous.
If not, and the language says that N1::f() should be called, all is well.

Anyways, The compiler should prefer N1::f() over the error ( again, if it's an error ).

The reason :

void f();

class X {
 void f();
 void g();
 };

void X::g() {
 f(); // here it's OK. calls X::f() and NOT ::f()
 }

Since the language is smart enough to say that X::f() is "more-related" to X::g() than ::f()...

This is quite reasonable : namespaces are actually WIDER class definitions, such that can be split among
several files. The functions have the namespace relationship in their names, exactly as member functions
( => the mangled name of X::g() will contain somewhere that it belongs to namespace X ).

If I'm NOT wrong, meaning that overloading between namespaces IS ambigiuous, I guess that treating
namespaces as WIDER classes will provide the answer to the discussed problem.

-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/10
Raw View
mfinney@inmind.com wrote:

>Its true, that the definition conflict will not occur unless both namespaces have a
>local using as in your example.  But, this is a case where (in my opinion) the

>Michael Lee Finney

My point is that the "search for function" rules should change. The local "using" is almost mandatory since,
I guess, no one wants to use qualification for each function.

Its trivial that the "conflict will not occur unless both namespaces have a local using". I'm saying that
its also trivial to solve the ambiguity.

The example again :

namespace N1 {
 void f();
 void g();
 };

namespace N2 {
 void f();
 };

using namespace N1;
using namespace N2;

void N1::g() {
 f(); // The standard says this is ambiguous. it should call N1::f()
 }

-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: mfinney@inmind.com
Date: 1995/08/10
Raw View
In <DD1oF2.AA1@research.att.com>, ark@research.att.com (Andrew Koenig) writes:
>In article <409bjt$59c@mujibur.inmind.com> mfinney@inmind.com writes:
>
>> The main problem is that far too much code will require a "using namespace std;"
>> along with my class libraries -- and then we get the conflict again.
>
>Why do you think so?

Like most people, I use parts of the standard library fairly heavily -- especially
the string manipulation functions, iostreams -- and hopefully soon STL.  This
means that virtually all of my source code contains one or more library headers
and the usual practice there, to match existing code, will be to have a
"using namespace std" present.  However, my own class library is extremely
extensive and is ALSO used very heavily.  Again, constant qualification will be
very annoying so that namespace will also be included.  Of course, normally
there are no conflicts between the namespaces, so there is no problem.

However, if STL is used (or is dragged in by another header, which is just fine
with me) then the definitions of these operators will cause a conflict.  I have
global template definitions of operators ==, != , <. <=, > and >= which map to,
respectively, x.isEqual(y), x.isNotEqual(y), etc..  Each class is free to implement
the underlying methods as inline functions and, where appropriate, make the
same type of short-cuts that STL makes.  In polymorphic classes, these are
usually virtual methods as well.  However, classes such as PartialOrder does
NOT (and should not) make such short-cuts because they are not mathematically
valid.  Since STL also defines these as global templates to avoid the necessity of
the user defining the operators, the STL definition conflicts with my definition.

So, if I am going to use the standard library and my library, both in the global
namespace -- which is the normal usage, the STL usage causes problems.

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/10
Raw View
In <40ba9d$5ij@lyman.pppl.gov>, Etay Bogner <Etay_Bogner@mail.stil.scitex.com> writes:
>The problem might be the overloading rules BETWEEN namespaces.

Its true, that the definition conflict will not occur unless both namespaces have a
local using as in your example.  But, this is a case where (in my opinion) the
standard should NOT have a definition that conflicts when the definition in STL
is mathematically incorrect for classes which are not linearly ordered.


Michael Lee Finney






Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/10
Raw View
I think that Andrew Koenig means that the header <string> will contain a
namespace declaration, but <string.h> will include <string> and contain
a "using namespace".

So, you won't have to add it yourself, so OLD sources should work fine.
The usage of the new headers ( <string> ) will require a qualification.

-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: mfinney@inmind.com
Date: 1995/08/07
Raw View
In <4023ic$sss@lyman.pppl.gov>, Haim Kreitman <haim_kreitman@mail.stil.scitex.com> writes:
>Another realistic and usefull example of partial order is
>//  (where @ means "non-comparable") could be helpfull)

Interesting example -- and one I had not (yet) considered.  But, of course, it is
worse than the templated operators are useless.  They actively conflict with
the correct template definitions.

BTW, instead of using x @ y to mean non-comparable, I use x  >< y where the
>< is intended to overlap.  It has the advantage of using the same characters
as <> so no new symbols are required (I also want to reserve @ for some other
things, but that is not really relevant here).

I haven't heard from Koenig or anyone from the the standard on this yet.  I
hope it isn't too late to get a correction into the standard.

It is possible that namespaces will make things a bit better, but it would be
pretty awkward to have to always use x.std::operator<=(y) instead of x <= y
so that isn't really a viable solution.

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/07
Raw View
In <MATT.95Aug7100148@godzilla.EECS.Berkeley.EDU>, matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
>In article <404gjm$bhu@mujibur.inmind.com> mfinney@inmind.com writes:
>
>
>Maybe I'm missing something, but I don't see anything in the standard
>that's in need of correction.
>
>Is there really any problem here that template specialization doesn't
>already solve?

When I wish to provide additional template operator definitions (non-member
functions) which map to specific functions, I have gotten template conflicts
because more than one template matches an instantiation.

In any case, those template definitions are clearly WRONG in general terms (as
many different examples show) and such a constraint should NOT be part of the
standard merely for the sake of "convenience" of the authors/users of STL.

Just because STL assumes a linear ordering over their iterators/collections does
NOT mean that the rest of the world can live with those constraints.

Michael Lee Finney






Author: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/08/07
Raw View
In article <404gjm$bhu@mujibur.inmind.com> mfinney@inmind.com writes:

> Interesting example -- and one I had not (yet) considered.  But, of
> course, it is worse than the templated operators are useless.  They
> actively conflict with the correct template definitions.
>
> BTW, instead of using x @ y to mean non-comparable, I use x  >< y where the
> >< is intended to overlap.  It has the advantage of using the same characters
> as <> so no new symbols are required (I also want to reserve @ for some other
> things, but that is not really relevant here).
>
> I haven't heard from Koenig or anyone from the the standard on this yet.  I
> hope it isn't too late to get a correction into the standard.

Maybe I'm missing something, but I don't see anything in the standard
that's in need of correction.  Yes, there's a template definition of
other comparison operators in terms of operator< and operator==, and
yes, that definition is incorrect for some types.  But isn't that what
template specialization is for?  If you have some type Foo for which
the default definitions are wrong, then you can just define
operator>(Foo, Foo) and be done with it.

Is there really any problem here that template specialization doesn't
already solve?
--
  Matt Austern                             He showed his lower teeth.  "We
  matt@physics.berkeley.edu                all have flaws," he said, "and
  http://dogbert.lbl.gov/~matt             mine is being wicked."





Author: Etay Bogner <Etay_Bogner@mail.stil.scitex.com>
Date: 1995/08/08
Raw View
Wouldn't the use of name spaces solve your problem ?

I hope this will work :

#include <function.h> // the STL Headers in which the problematic templates are defined

namespace X {
  template <class T>
  inline bool operator<=(const T& x, const T& y) {
     // your special implementation
  }
 // here will also go all the USERs ( i.e. classes ) of your partial order lists
 }

using namespace X;

// the USERs of your lists

The only overhead here is that all the users must be in the same namespace as your
templates, or better yet, in their own namespace, with a using namespace in it, to use
namespace X.

Another overhead is to wait for a compiler which implements namespaces :-).

-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: mfinney@inmind.com
Date: 1995/08/04
Raw View
In <3vq030$8v1@lyman.pppl.gov>, Etay Bogner <ebogner@ird.scitex.com> writes:
>I think that declaring those operators that you don't want to be genereted by the
>operator templates as private, without definitions would do the job.

You misunderstand...these classes declare all of these as public operators.  The
only restriction is that you CANNOT, for example, define (a <= b) == !(a > b).

Basically, the only problem with STL is that it defines these operators in just
this way to avoid making the user actually define the operators.  But, even if
I did not have the partial order restriction, I often find it is preferrable to
define these myself for greater efficiency.

Now, explicitly defined operators for a class works o.k., but if they are defined
as templates (but NOT the same as the STL definitions) then there is a template
conflict with the STL definitions.  And the only solution is to...

   a) redesign my class library, in the process eliminating many useful classes,

   b) live with the STL definitions -- which are WRONG and therefore will cause
       code to work incorrectly,

   c) simply not use the STL classes -- which is, itself, very useful,

   d) fix STL so that it does not make mathematically invalid assumptions
       "across the board", or

   e) partially disable STL -- however, since the C++ Draft Standard
       says that headers may not be actual host system source files, it
      may not be possible to edit those headers to remove the offending
      definitions, so this approach must be done through a mechanism
      defined in the standard itself.

Michael Lee Finney






Author: Etay Bogner <ebogner@ird.scitex.com>
Date: 1995/08/04
Raw View
Sorry, I didn't read your first article till the end.

I guess that the right way is to use solution "b".

I'm saying this because I can't imagine why the results will be incorrect.

For example, you defined operator< and operator==. Since I'm sure you did
your best, I can't see why the inline template function which is invoked for
"a operator> b", which produces "b operator< a", is incorrect ...

Just for those classes that you don't want those templates to be generated,
you should use the solution in my first article.

-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: mfinney@inmind.com
Date: 1995/08/05
Raw View
In <3vtcha$cbv@lyman.pppl.gov>, Etay Bogner <ebogner@ird.scitex.com> writes:
>I guess that the right way is to use solution "b".
>
>I'm saying this because I can't imagine why the results will be incorrect.
>
>For example, you defined operator< and operator==. Since I'm sure you did
>your best, I can't see why the inline template function which is invoked for
>"a operator> b", which produces "b operator< a", is incorrect ...

The problem is not defined < in terms of > or vice versa, but defined <= in
terms of >.  In a linear order there are three possibilities, a < b, a = b or a > b.
In a partial order there are four possibilities, a < b, a = b, a > b or a >< b (using
operator >< () mean "not comparable).

For a linear order, a <= b is equivalent to not (a > b).  However, that fails to
be true for a partial order because there is an extra possiblity.

If <= were defined in terms of > (or >= in terms of <) for IEEE floating point
then even there there would be a problem because there are NaNs (not a number)
objects in IEEE floating point which are not comparable to anything else,
including other NaNs.

This is why the definitions are wrong.

Michael Lee Finney






Author: Haim Kreitman <haim_kreitman@mail.stil.scitex.com>
Date: 1995/08/06
Raw View
Another realistic and usefull example of partial order is
representation of the field R+R (i.e. pairs of real numbers with by
coordinate add, subtract, multiply and divide. The 'ONE' in this ring is
the pair {1,1} and the 'ZERO' - the pair {0,0} )

class FloatFloat {
    float first;
    float second;
public:
    FloatFloat(double d=0)              { first=second=d;}
    FloatFloat(double d1,double d2)     { first=d1; second=d2;}
    FloatFloat operator+(const FloatFloat& ff) const
        { return FloatFloat(first+ff.first , second+ff.second;}
    FloatFloat operator*(const FloatFloat& ff) const
        { return FloatFloat(first*ff.first , second*ff.second;}
// etc... all arithmetics
    bool operator==(const FloatFloat& ff)
        { return first==ff.first && second==ff.second;}
//  The templated operator != is good.

    bool operator <(const FloatFloat& ff) const
        { return first < ff.first && second < ff.second;
//  Usual partial order in the R+R ring. Can be used for
//  checking of inclusion of rectangles in graphic software.
//  Here the templated definitions are useless, because of the
//  partial oreder and additional bool operator@
//  (where @ means "non-comparable") could be helpfull)

};








Author: Etay Bogner <ebogner@ird.scitex.com>
Date: 1995/08/03
Raw View
I think that declaring those operators that you don't want to be genereted by the
operator templates as private, without definitions would do the job.

something like :

class X {
  ...
  private :
   bool operator >( ... ) ; // no need for a definition
  };

so the compiler will generate COMPILE errors iff anybody tries to use those
EXPLICITLY, and it will NOT generate the template operators ...


-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.







Author: mfinney@inmind.com
Date: 1995/08/03
Raw View
In the 28 April 1995 Draft Standard (which I was only able to download last week)
section 20.2.1 says that the STL portion of the Standard Library will define
operator!=(), operator>(), operator<=() and operator>=() in terms of operator=()
and operator<().

This breaks my code!  And NOT in a fixable fashion!

In particular, I have a PartialOrder class (which is a base class of LinearOrder)
and the assumption that these operators can so be defined is ONLY valid for
linear orders.  In a partial order "<" is equivalent to "=", ">" or "uncomparable"
which is not at all the same thing as "=" or ">".

It is extremely convenient to use the same operators in the PartialOrder class
as in the LinearOrder class (as, indeed, they really ARE the same operators)
and inclusion of the template definition of these operators conflicts with my
definitions -- which are NOT allowed to take the convenient shortcuts assumed
by the STL authors.

Is there any standard way to disable this "feature" of the STL portion of the
library?  If not, this essentially means that I cannot use the STL abilities which
are, in general, very nice.

HELP!

Michael Lee Finney






Author: mfinney@inmind.com
Date: 1995/08/03
Raw View
>linear orders.  In a partial order "<" is equivalent to "=", ">" or "uncomparable"
>which is not at all the same thing as "=" or ">".

Oops!  I meant...

In a partial order not "<" is equivalent to "=", ">" or "uncomparable"
which is not at all the same thing as "=" or ">".

Michael Lee Finney






Author: Joe Borkoles <jborkole@jpmorgan.com>
Date: 1995/08/03
Raw View
mfinney@inmind.com wrote:
>In the 28 April 1995 Draft Standard (which I was only able to download last week)
>section 20.2.1 says that the STL portion of the Standard Library will define
>operator!=(), operator>(), operator<=() and operator>=() in terms of operator=()
>and operator<().
>
>This breaks my code!  And NOT in a fixable fashion!
>

I too have been finding these operators quite annoying and forcing me to reorder my
header files in a most unpleasant fashion. I have had some discussion with
colleagues and we thought that breaking up the standard library into
hierarchical namespaces might be the way to go.


-----------------------------------
I speak for myself and no one else.