www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - strong enums: why implicit conversion to basetype?

reply "Trass3r" <un known.com> writes:
I thought it'd be good to outsource this question from the other 
thread about enums as flags.

Is there any merit in having implicit conversion to the basetype?
Imo it only introduces a severe bug source and brings no 
advantages.

For example it allows implicit conversion to bool.

enum Bla
{
    S1 = 1,
    S2,
    S3
}
if (Bla.S2) // makes no sense at all, all Blas convert to true
// and if S1 was 0, it would mean false, but it isn't meant as a 
special member!

A better example is something like
if (b && Bla.S2) // written '&&' instead of '&' by mistake, will 
silently pass


In general it allows operations that don't make any sense.

if (Bla.S2 & Blub.S1) // works cause an int is produced
// but by using named enums I made clear that Bla and Blub are 
totally different

Heck even +,-,... work.

Remember that if you do need to do such crazy stuff you can still 
explicitly cast to int or whatever.
Jan 26 2012
next sibling parent reply "Trass3r" <un known.com> writes:
On Thursday, 26 January 2012 at 14:45:02 UTC, Manfred Nowak wrote:
 Trass3r wrote:

 but by using named enums I made clear that Bla and Blub are 
 totally different

No. Obviously you decjlared both to be implicitely convertable to a common super type: int. To change this, both supertypes have be changed.

No. The intention is "Bla and Blub don't have anything to do with each other". That's why I question the implicit conversion.
Jan 26 2012
parent Manfred Nowak <svv1999 hotmail.com> writes:
Trass3r wrote:

 That's why I question the implicit conversion.

Yes. I realized my fault and canceled my message, but wasn't fast enough. -manfred
Jan 26 2012
prev sibling next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Trass3r wrote:

 Is there any merit in having implicit conversion to the basetype?

Yes. Otherwise it would be at least close to equivalence to a `typedef'. -manfred
Jan 26 2012
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Trass3r wrote:


 Even typedef implicitly converts in one of the directions.

`typedef' is or will be disallowed in D because of reasons I do not understand. In C and C++ their existence introduce problems because they increase the amount of parsing passes.
 A named enum is a separate type with a finite set of allowed 
 values defined by the user.

Both wrong according to the currently published reference: 1) "The enum EnumTag declares a new type, and all the EnumMembers have that type.", i.e. it is the tag not the hole enum that produces a new type. 2) "Enum declarations are used to define a group of constants.", i.e. only some of the valid values of the basetype are given names. All of the valid values of the basetype are also valid in the type declared by the tag. 3) "An EmptyEnumBody signifies an opaque enum - the enum members are unknown", i.e. none of the valied values of the basetype has got a name, but all valid values of the basetype are also valid in the type declared by the tag. B) It is somehow difficult to write about the reference because the use of the terms declaration, definition or declaration follows rules, which I have not yet detected. I use "declaration" for any entity, which is undefined at the current position of reading _and_ will be defined after that position is passed. This is often an identifier in D. I use "definition" for any entity, which represents the content of the transition from undefined to defined. This is often a type in D. I use "specification" for those two entities, which represents a binding between a declaration and a definition. This is often the absence of operators in D. -manfred
Jan 26 2012
parent Manfred Nowak <svv1999 hotmail.com> writes:
Trass3r wrote:

 It's ill-defined. There are 4 possible types of typedef:  
 http://d.puremagic.com/issues/show_bug.cgi?id=5467

 Again, this thread is all about discussing the right way to do it
 and not  about what the buggy and holey spec reads.

 I don't see any merit in that.

You meight be blind. The only way to eject this possibility is to prove that there cannot be any merit. Currently a good approximation of your intentions for the replacment of `enum's seems to be a wood of rooted almost-DAGs on types, where the edges in the DAGs represent the allowed implicit conversions, the inner nodes are represented by tags and the leaves are represented by members. Maybe that the "almost" is not necessary. -manfred
Jan 26 2012
prev sibling next sibling parent "Trass3r" <un known.com> writes:
 Is there any merit in having implicit conversion to the 
 basetype?

Yes. Otherwise it would be at least close to equivalence to a `typedef'.

Even typedef implicitly converts in one of the directions. A named enum is a separate type with a finite set of allowed values defined by the user.
Jan 26 2012
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/26/2012 02:59 PM, Trass3r wrote:
 I thought it'd be good to outsource this question from the other thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages.

 For example it allows implicit conversion to bool.

 enum Bla
 {
 S1 = 1,
 S2,
 S3
 }
 if (Bla.S2) // makes no sense at all, all Blas convert to true
 // and if S1 was 0, it would mean false, but it isn't meant as a special
 member!

That is not an implicit conversion. if(x) is equivalent to if(cast(bool)x).
 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass


 In general it allows operations that don't make any sense.

 if (Bla.S2 & Blub.S1) // works cause an int is produced
 // but by using named enums I made clear that Bla and Blub are totally
 different

 Heck even +,-,... work.

 Remember that if you do need to do such crazy stuff you can still
 explicitly cast to int or whatever.

I have argued for banning those operations on strong enums before, but some objected to it because they wanted to use strong enums as bit flags.
Jan 26 2012
prev sibling next sibling parent deadalnix <deadalnix gmail.com> writes:
Le 26/01/2012 14:59, Trass3r a écrit :
 I thought it'd be good to outsource this question from the other thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages.

 For example it allows implicit conversion to bool.

 enum Bla
 {
 S1 = 1,
 S2,
 S3
 }
 if (Bla.S2) // makes no sense at all, all Blas convert to true
 // and if S1 was 0, it would mean false, but it isn't meant as a special
 member!

 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass


 In general it allows operations that don't make any sense.

 if (Bla.S2 & Blub.S1) // works cause an int is produced
 // but by using named enums I made clear that Bla and Blub are totally
 different

 Heck even +,-,... work.

 Remember that if you do need to do such crazy stuff you can still
 explicitly cast to int or whatever.

I don't see any problem with that : it is perfectly safe. The other way around isn't and isn't allowed, so the current behaviour seems fine to me.
Jan 26 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 I have argued for banning those operations on strong enums before, but  
 some objected to it because they wanted to use strong enums as bit flags.

Yep, that's what the other thread 'using enums for flags' is about. But implicit conversions seem wrong in any case.
Jan 26 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 `typedef' is or will be disallowed in D because of reasons I do not
 understand.

It's ill-defined. There are 4 possible types of typedef: http://d.puremagic.com/issues/show_bug.cgi?id=5467
 In C and C++ their existence introduce problems because
 they increase the amount of parsing passes.

C's typedef is equal to D's alias.
 A named enum is a separate type with a finite set of allowed
 values defined by the user.

Both wrong according to the currently published reference:

Again, this thread is all about discussing the right way to do it and not about what the buggy and holey spec reads.
 2) "Enum declarations are used to define a group of constants.", i.e. 
 only some of the valid values of the basetype are given names. All ofthe  
 valid values of the basetype are also valid

That's what anonymous enums are for.
 3) "An EmptyEnumBody signifies an opaque enum - the enum members are
 unknown", i.e. none of the valied values of the basetype has got a
 name, but all valid values of the basetype are also valid in the type
 declared by the tag.

So the only purpose is to create a new type similar to typedef. I don't see any merit in that.
Jan 26 2012
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
On 26.01.2012 14:59, Trass3r wrote:
 I thought it'd be good to outsource this question from the other thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?

Allowing it to be used as an argument when calling C functions? Without it, how would you support eg the Windows API?
Jan 26 2012
parent Don Clugston <dac nospam.com> writes:
On 26/01/12 21:26, Trass3r wrote:
 Is there any merit in having implicit conversion to the basetype?

Allowing it to be used as an argument when calling C functions?

extern(C): enum Bla : int {...} void foo(Bla b); How does this require implicit conversion? The codegen treats Bla like basetype anyway.

Some of the Windows functions are made of multiple enums of different types, ORed together.
Jan 27 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 Is there any merit in having implicit conversion to the basetype?

Allowing it to be used as an argument when calling C functions?

extern(C): enum Bla : int {...} void foo(Bla b); How does this require implicit conversion? The codegen treats Bla like basetype anyway.
Jan 26 2012
prev sibling next sibling parent reply Alvaro <alvaroDotSegura gmail.com> writes:
El 26/01/2012 14:59, Trass3r escribió:
 I thought it'd be good to outsource this question from the other thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages.

 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass
 Heck even +,-,... work.

I kind of agree. I understand enums as a way to define "tags" or flags used to define things like file open mode Read, Write, ReadWrite, endianness BigEndian, LittleEndian, socket type Stream/Packet, etc. things that under the hood are represented by integer numbers but that don't represent *quantities*, so should not work the same way as integers. What is the result of subtracting or multiplying LittleEndian and BigEndian? Does not make sense. Bitwise operations would be OK because logica tags can be combined, but little more. And this brings the question of whether implicit casting from int to bool is a good thing (or making any integer a valid boolean value). The same way, true and false are not quantities and can't be used in arithmetic. Even if they are internally represented as 1 and 0, they should not be the same thing as numbers. IMO, Java did it better in making them distinct. With a non-int-convertible bool your above weird example would not work.
Jan 26 2012
next sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Alvaro wrote:

  With a non-int-convertible bool your above weird 
 example would not work.

But that the example works is not the fault of the existence of enums. It is due to the fact that omission, inclusion or change of one character can produce a different value without any warning. -manfred
Jan 26 2012
prev sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 01/26/2012 08:17 PM, Simen Kjærås wrote:
 On Thu, 26 Jan 2012 23:49:40 +0100, Alvaro <alvaroDotSegura gmail.com>
 wrote:

 El 26/01/2012 14:59, Trass3r escribió:
 I thought it'd be good to outsource this question from the other thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages.

 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass
 Heck even +,-,... work.

I kind of agree. I understand enums as a way to define "tags" or flags used to define things like file open mode Read, Write, ReadWrite, endianness BigEndian, LittleEndian, socket type Stream/Packet, etc. things that under the hood are represented by integer numbers but that don't represent *quantities*, so should not work the same way as integers. What is the result of subtracting or multiplying LittleEndian and BigEndian? Does not make sense. Bitwise operations would be OK because logica tags can be combined, but little more.

Sometimes, bitwise operations make sense, other times not. Enums play two roles in D - that of an enumeration and that of a set of flags. Only for the latter do bitwise operations make sense.

You'd think that with some use of a templated struct and some "alias this" we'd be able to have a strongly-typed type for storing sets of flags. It could even offer convenience functions like "getFlag" and "setFlag" to make the code read a bit nicer.
Jan 27 2012
prev sibling next sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Thu, 26 Jan 2012 23:49:40 +0100, Alvaro <alvaroDotSegura gmail.com>
wrote:

 El 26/01/2012 14:59, Trass3r escribi=C3=B3:
 I thought it'd be good to outsource this question from the other thre=


 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages.

 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass
 Heck even +,-,... work.

I kind of agree. I understand enums as a way to define "tags" or flags=

 used to define things like file open mode Read, Write, ReadWrite,  =

 endianness BigEndian, LittleEndian, socket type Stream/Packet, etc.  =

 things that under the hood are represented by integer numbers but that=

 don't represent *quantities*, so should not work the same way as  =

 integers. What is the result of subtracting or multiplying LittleEndia=

 and BigEndian? Does not make sense. Bitwise operations would be OK  =

 because logica tags can be combined, but little more.

Sometimes, bitwise operations make sense, other times not. Enums play tw= o roles in D - that of an enumeration and that of a set of flags. Only for= the latter do bitwise operations make sense.
Jan 26 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 extern(C):
 enum Bla : int {...}
 void foo(Bla b);

 How does this require implicit conversion?
 The codegen treats Bla like basetype anyway.

Some of the Windows functions are made of multiple enums of different types, ORed together.

-.- Microsuckx. Then I think it should either become a combined enum or just anonymous ones (+ aliases to basetype perhaps).
Jan 27 2012
prev sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
------------5uSTsBe9rureIZClGe1vta
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes
Content-Transfer-Encoding: Quoted-Printable

On Fri, 27 Jan 2012 13:34:06 +0100, Chad J  =

<chadjoan __spam.is.bad__gmail.com> wrote:

 On 01/26/2012 08:17 PM, Simen Kj=C3=A6r=C3=A5s wrote:
 On Thu, 26 Jan 2012 23:49:40 +0100, Alvaro <alvaroDotSegura gmail.com=

 wrote:

 El 26/01/2012 14:59, Trass3r escribi=C3=B3:
 I thought it'd be good to outsource this question from the other  =




 thread
 about enums as flags.

 Is there any merit in having implicit conversion to the basetype?
 Imo it only introduces a severe bug source and brings no advantages=




 A better example is something like
 if (b && Bla.S2) // written '&&' instead of '&' by mistake, will
 silently pass
 Heck even +,-,... work.

I kind of agree. I understand enums as a way to define "tags" or fla=



 used to define things like file open mode Read, Write, ReadWrite,
 endianness BigEndian, LittleEndian, socket type Stream/Packet, etc.
 things that under the hood are represented by integer numbers but th=



 don't represent *quantities*, so should not work the same way as
 integers. What is the result of subtracting or multiplying
 LittleEndian and BigEndian? Does not make sense. Bitwise operations
 would be OK because logica tags can be combined, but little more.

Sometimes, bitwise operations make sense, other times not. Enums play=


 two
 roles in D - that of an enumeration and that of a set of flags. Only =


 the latter do bitwise operations make sense.

You'd think that with some use of a templated struct and some "alias =

 this" we'd be able to have a strongly-typed type for storing sets of  =

 flags.  It could even offer convenience functions like "getFlag" and  =

 "setFlag" to make the code read a bit nicer.

Like that attached? ------------5uSTsBe9rureIZClGe1vta Content-Disposition: attachment; filename=flags.d Content-Type: application/octet-stream; name="flags.d" Content-Transfer-Encoding: Base64 77u/bW9kdWxlIGZsYWdzOwoKaW1wb3J0IHN0ZC50eXBldHVwbGU7CmltcG9ydCBz dGQuYXJyYXk7CgpwdXJlOgpub3Rocm93OgpAc2FmZToKcHJpdmF0ZToKCnRlbXBs YXRlIGlzVmFsaWRGbGFnRW51bUJvZHkoIHN0cmluZyBzICkgewoJZW51bSBpc1Zh bGlkRmxhZ0VudW1Cb2R5ID0gX190cmFpdHMoIGNvbXBpbGVzLCB7IG1peGluKCAi ZW51bSBmb28geyAiIH4gcyB+ICIgfSIgKTsgfSApOwp9Cgp1bml0dGVzdCB7Cglh c3NlcnQoIGlzVmFsaWRGbGFnRW51bUJvZHkhcXthfSApOwoJYXNzZXJ0KCBpc1Zh bGlkRmxhZ0VudW1Cb2R5IXF7YSxifSApOwoJYXNzZXJ0KCAhaXNWYWxpZEZsYWdF bnVtQm9keSFxe2EufSApOwp9Cgp0ZW1wbGF0ZSBNYWtlRW51bSggc3RyaW5nIHMg KSB7CgltaXhpbiggImVudW0gTWFrZUVudW0geyAiIH4gcyB+ICIgfSIgKTsKfQoK dGVtcGxhdGUgcGFyc2VkU3RyaW5nKCBzdHJpbmcgcyApIHsKCWFsaWFzIFR5cGVU dXBsZSEoIF9fdHJhaXRzKCBhbGxNZW1iZXJzLCBNYWtlRW51bSFzICkgKSBwYXJz ZWRTdHJpbmc7Cn0KCnVuaXR0ZXN0IHsKCWFzc2VydCggcGFyc2VkU3RyaW5nISJh IlswXSA9PSAiYSIgKTsKCWFzc2VydCggcGFyc2VkU3RyaW5nISJhIi5sZW5ndGgg PT0gMSApOwoJYXNzZXJ0KCBwYXJzZWRTdHJpbmchImEsYiJbMF0gPT0gImEiICk7 Cglhc3NlcnQoIHBhcnNlZFN0cmluZyEiYSxiIlsxXSA9PSAiYiIgKTsKCWFzc2Vy dCggcGFyc2VkU3RyaW5nISJhLGIiLmxlbmd0aCA9PSAyICk7Cn0KCi8qKgpSZXBy ZXNlbnRzIGEgc2V0IG9mIGZsYWdzLgoKVGhlc2UgY2FuIGJlIG1hbmlwdWxhdGVk IHZpYSByZWd1bGFyIGJpdHdpc2Ugb3BlcmF0b3JzIC0gfCwgJiwgYW5kIF4uCgpF eGFtcGxlOgotLS0tCmFsaWFzIEZsYWdzIXF7CiAgICBBLAoJQgp9IG15RmxhZ3M7 Cm15RmxhZ3MgYSA9IG15RmxhZ3MuQSB8IG15RmxhZ3MuQjsKYXNzZXJ0KCBhICYg bXlGbGFncy5BICk7CmFzc2VydCggYSAmIG15RmxhZ3MuQiApOwotLS0tCioqLwpw dWJsaWMKc3RydWN0IEZsYWdzKCBzdHJpbmcgcyApIGlmICggaXNWYWxpZEZsYWdF bnVtQm9keSFzICYmIHBhcnNlZFN0cmluZyFzLmxlbmd0aCA8PSA2NCApIHsKCXBy aXZhdGUgYWxpYXMgcGFyc2VkU3RyaW5nIXMgbWVtYmVyTmFtZXM7CglzdGF0aWMg aWYgKCBtZW1iZXJOYW1lcy5sZW5ndGggPD0gOCApIHsKCQlwcml2YXRlIGFsaWFz IHVieXRlIFJlcHJlc2VudGF0aW9uOwoJfSBlbHNlIHN0YXRpYyBpZiAoIG1lbWJl ck5hbWVzLmxlbmd0aCA8PSAxNiApIHsKCQlwcml2YXRlIGFsaWFzIHVzaG9ydCBS ZXByZXNlbnRhdGlvbjsKCX0gZWxzZSBzdGF0aWMgaWYgKCBtZW1iZXJOYW1lcy5s ZW5ndGggPD0gMzIgKSB7CgkJcHJpdmF0ZSBhbGlhcyB1aW50IFJlcHJlc2VudGF0 aW9uOwoJfSBlbHNlIHN0YXRpYyBpZiAoIG1lbWJlck5hbWVzLmxlbmd0aCA8PSA2 NCApIHsKCQlwcml2YXRlIGFsaWFzIHVsb25nIFJlcHJlc2VudGF0aW9uOwoJfQoJ cHJpdmF0ZSBSZXByZXNlbnRhdGlvbiB2YWx1ZTsKCgltaXhpbiB0ZW1wbGF0ZSBm bGFnc01lbWJlcnMoIGludCBOICkgewoJfQoKCW1peGluIHRlbXBsYXRlIGZsYWdz TWVtYmVycyggaW50IE4sIHN0cmluZyBULCBVLi4uICkgewoJCW1peGluKCAiZW51 bSAiIH4gVCB+ICIgPSBGbGFncyggMUwgPDwgTiApOyIgKTsKCQltaXhpbiBmbGFn c01lbWJlcnMhKCBOICsgMSwgVSApOwoJfQoJCgltaXhpbiBmbGFnc01lbWJlcnMh KCAwLCBtZW1iZXJOYW1lcyApOwoJCglwcml2YXRlIHRoaXMoIFJlcHJlc2VudGF0 aW9uIHZhbHVlICkgewoJCXRoaXMudmFsdWUgPSB2YWx1ZTsKCX0KCQoJRmxhZ3Mg b3BCaW5hcnkoIHN0cmluZyBvcCApKCBGbGFncyBvdGhlciApIGNvbnN0IGlmICgg b3AgPT0gInwiIHx8IG9wID09ICJeIiB8fCBvcCA9PSAiJiIgKSB7CgkJbWl4aW4o ICJyZXR1cm4gRmxhZ3MoIHZhbHVlICIgfiBvcCB+ICIgb3RoZXIudmFsdWUgKTsi ICk7Cgl9CgkKCXJlZiBGbGFncyBvcE9wQXNzaWduKCBzdHJpbmcgb3AgKSggRmxh Z3Mgb3RoZXIgKSBpZiAoIG9wID09ICJ8IiB8fCBvcCA9PSAiXiIgfHwgb3AgPT0g IiYiICkgewoJCW1peGluKCAidmFsdWUgIiB+IG9wIH4gIj0gb3RoZXIudmFsdWU7 IiApOwoJCXJldHVybiB0aGlzOwoJfQoJCglSZXByZXNlbnRhdGlvbiBvcENhc3Qo IFQgKSggKSBjb25zdCBpZiAoIGlzKCBSZXByZXNlbnRhdGlvbiA6IFQgKSApIHsK CQlyZXR1cm4gdmFsdWU7Cgl9CgkKCWJvb2wgb3BDYXN0KCBUIDogYm9vbCApKCAp IGNvbnN0IHsKCQlyZXR1cm4gdmFsdWUgIT0gMDsKCX0KCQoJQHRydXN0ZWQKCXN0 cmluZyB0b1N0cmluZyggKSBjb25zdCB7CgkJc3RyaW5nW10gcmVzdWx0OwoJCQoJ CWZvcmVhY2ggKGksIGU7IG1lbWJlck5hbWVzKSB7CgkJCWlmICh2YWx1ZSAmICgg MUwgPDwgaSApICkgewoJCQkJcmVzdWx0IH49IGU7CgkJCX0KCQl9CgkJCgkJcmV0 dXJuICI8IiB+IHJlc3VsdC5qb2luKCIsICIpIH4gIj4iOwoJfQoJCglAdHJ1c3Rl ZAoJc3RhdGljIGludCBvcEFwcGx5KCBpbnQgZGVsZWdhdGUocmVmIEZsYWdzKSBm biApIHsKCQlmb3JlYWNoICggZTsgbWVtYmVyTmFtZXMgKSB7CgkJCWlmICggYXV0 byByZXQgPSBmbiggbWl4aW4oICJGbGFncy4iIH4gZSApICkgIT0gMCApIHsKCQkJ CXJldHVybiByZXQ7CgkJCX0KCQl9CgkJcmV0dXJuIDA7Cgl9CgkKCUB0cnVzdGVk CglzdGF0aWMgaW50IG9wQXBwbHkoIGludCBkZWxlZ2F0ZShyZWYgaW50LCByZWYg RmxhZ3MpIGZuICkgewoJCWZvcmVhY2ggKCBpLCBlOyBtZW1iZXJOYW1lcyApIHsK CQkJaW50IG4gPSBpOwoJCQlpZiAoIGF1dG8gcmV0ID0gZm4oIG4sIG1peGluKCAi RmxhZ3MuIiB+IGUgKSApICE9IDAgKSB7CgkJCQlyZXR1cm4gcmV0OwoJCQl9CgkJ fQoJCXJldHVybiAwOwoJfQp9Cgp1bml0dGVzdCB7CgkvLyBUZXN0IHNpemVzIG9m IGNyZWF0ZWQgdHlwZXMuCglhbGlhcyBGbGFncyEiYSIgbXlGbGFnczE7CglhbGlh cyBGbGFncyEiYSxiLGMsZCxlLGYsZyxoLGksaixrLGwsbSxuLG8scCIgbXlGbGFn czI7CglhbGlhcyBGbGFncyEiYTEsYjEsYzEsZDEsZTEsZjEsZzEsaDEsaTEsajEs azEsbDEsbTEsbjEsbzEscDEsczEsYTIsYjIsYzIsZDIsZTIsZjIsZzIsaDIsaTIs ajIsazIsbDIsbTIsbjIsbzIiIG15RmxhZ3MzOwoJYWxpYXMgRmxhZ3MhImExLGIx LGMxLGQxLGUxLGYxLGcxLGgxLGkxLGoxLGsxLGwxLG0xLG4xLG8xLHAxLHMxLGEy LGIyLGMyLGQyLGUyLGYyLGcyLGgyLGkyLGoyLGsyLGwyLG0yLG4yLG8yLHAyLHMy LGEzLGIzLGMzLGQzLGUzLGYzLGczLGgzLGkzLGozLGszLGwzLG0zLG4zLG8zLHAz LHMzLGE0LGI0LGM0LGQ0LGU0LGY0LGc0LGg0LGk0LGo0LGs0LGw0LG00IiBteUZs YWdzNDsKCWFzc2VydCggbXlGbGFnczEuc2l6ZW9mID09IDEgKTsKCWFzc2VydCgg bXlGbGFnczIuc2l6ZW9mID09IDIgKTsKCWFzc2VydCggbXlGbGFnczMuc2l6ZW9m ID09IDQgKTsKCWFzc2VydCggbXlGbGFnczQuc2l6ZW9mID09IDggKTsKCQoJLy8g VGVzdCB0aGF0IHZhbGlkIHR5cGVzIGRvIGNvbXBpbGUsIGFuZCBpbnZhbGlkIHR5 cGVzIG5vdC4KCWFzc2VydCggX190cmFpdHMoIGNvbXBpbGVzLCBGbGFncyEiYSIg KSApOwoJYXNzZXJ0KCBfX3RyYWl0cyggY29tcGlsZXMsIEZsYWdzISJhLCBiIiAp ICk7Cglhc3NlcnQoICFfX3RyYWl0cyggY29tcGlsZXMsIEZsYWdzISIiICkgKTsK CWFzc2VydCggIV9fdHJhaXRzKCBjb21waWxlcywgRmxhZ3MhImEuIiApICk7Cglh c3NlcnQoICFfX3RyYWl0cyggY29tcGlsZXMsIEZsYWdzISJhMSxiMSxjMSxkMSxl MSxmMSxnMSxoMSxpMSxqMSxrMSxsMSxtMSxuMSxvMSxwMSxzMSxhMixiMixjMixk MixlMixmMixnMixoMixpMixqMixrMixsMixtMixuMixvMixwMixzMixhMyxiMyxj MyxkMyxlMyxmMyxnMyxoMyxpMyxqMyxrMyxsMyxtMyxuMyxvMyxwMyxzMyxhNCxi NCxjNCxkNCxlNCxmNCxnNCxoNCxpNCxqNCxrNCxsNCxtNCxuNCIgKSApOwoJCglh bGlhcyBGbGFncyFxeyBhLCBiIH0gVGVzdEZsYWdzOwoJCgkvLyBUZXN0IHRoYXQg b3BlcmF0b3JzIHdvcmsuCglhdXRvIG8gPSBUZXN0RmxhZ3MuYSB8IFRlc3RGbGFn cy5iOwoJYXNzZXJ0KCBvICE9IFRlc3RGbGFncy5hICk7Cglhc3NlcnQoIG8gIT0g VGVzdEZsYWdzLmIgKTsKCWFzc2VydCggby52YWx1ZSAhPSAwICk7CgkKCWF1dG8g cCA9IG8gXiBUZXN0RmxhZ3MuYTsKCWFzc2VydCggcCA9PSBUZXN0RmxhZ3MuYiAp OwoJYXNzZXJ0KCBwICE9IFRlc3RGbGFncy5hICk7CgkKCWF1dG8gcSA9IG8gJiBU ZXN0RmxhZ3MuYTsKCWFzc2VydCggcSA9PSBUZXN0RmxhZ3MuYSApOwoJYXNzZXJ0 KCBvICE9IFRlc3RGbGFncy5iICk7CgkKCW8gJj0gVGVzdEZsYWdzLmE7Cglhc3Nl cnQoIG8gPT0gVGVzdEZsYWdzLmEgKTsKCQoJcCB8PSBUZXN0RmxhZ3MuYTsKCWFz c2VydCggcCA9PSAoIFRlc3RGbGFncy5hIHwgVGVzdEZsYWdzLmIgKSApOwoJCglx IF49IFRlc3RGbGFncy5hOwoJYXNzZXJ0KCBxLnZhbHVlID09IDAgKTsKCQoJCgkv LyBUZXN0IHRvU3RyaW5nLgoJYXNzZXJ0KCBUZXN0RmxhZ3MuYS50b1N0cmluZygp ID09ICI8YT4iICk7Cglhc3NlcnQoIFRlc3RGbGFncy5iLnRvU3RyaW5nKCkgPT0g IjxiPiIgKTsKCWFzc2VydCggKCBUZXN0RmxhZ3MuYSB8IFRlc3RGbGFncy5iICku dG9TdHJpbmcoKSA9PSAiPGEsIGI+IiApOwoJYXNzZXJ0KCBUZXN0RmxhZ3MoKS50 b1N0cmluZygpID09ICI8PiIgKTsKCQoJLy8gVGVzdCBjYXN0aW5nLgoJYXNzZXJ0 KCAhVGVzdEZsYWdzKCkgKTsKCWFzc2VydCggVGVzdEZsYWdzLmEgKTsKCWFzc2Vy dCggVGVzdEZsYWdzLmIgKTsKCWFzc2VydCggVGVzdEZsYWdzLmEgfCBUZXN0Rmxh Z3MuYiApOwoJYXNzZXJ0KCBjYXN0KGJvb2wpVGVzdEZsYWdzKCkgPT0gZmFsc2Ug KTsKCWFzc2VydCggY2FzdChib29sKVRlc3RGbGFncy5hID09IHRydWUgKTsKCWFz c2VydCggY2FzdChpbnQpVGVzdEZsYWdzKCkgPT0gMCApOwoJYXNzZXJ0KCBjYXN0 KGludClUZXN0RmxhZ3MuYSAhPSAwICk7CgkKCS8vIFRlc3QgaW52YWxpZCBjb21w YXJpc29ucy4KCWFzc2VydCggIV9fdHJhaXRzKCBjb21waWxlcywgeyBUZXN0Rmxh Z3MuYSA9PSAxOyB9ICkgKTsKCWFzc2VydCggIV9fdHJhaXRzKCBjb21waWxlcywg eyBUZXN0RmxhZ3MuYSA9PSB0cnVlOyB9ICkgKTsKCQoJLy8gVGVzdCBpbnZhbGlk IGNvbnZlcnNpb25zLgoJYXNzZXJ0KCAhX190cmFpdHMoIGNvbXBpbGVzLCB7IGlu dCBpID0gVGVzdEZsYWdzLmE7IH0gKSApOwoJYXNzZXJ0KCAhX190cmFpdHMoIGNv bXBpbGVzLCB7IGJvb2wgYiA9IFRlc3RGbGFncy5hOyB9ICkgKTsKCQoJLy8gVGVz dCBvcGVyYXRvcnMgd2l0aCBpbnZhbGlkIHR5cGVzLgoJYXNzZXJ0KCAhX190cmFp dHMoIGNvbXBpbGVzLCB7IGF1dG8gdG1wID0gVGVzdEZsYWdzLmIgfCBteUZsYWdz MS5hOyB9ICkgKTsKCWFzc2VydCggIV9fdHJhaXRzKCBjb21waWxlcywgeyBhdXRv IHRtcCA9IFRlc3RGbGFncy5iIHwgMTsgfSApICk7CgkKCW8gPSBUZXN0RmxhZ3Mu YSB8IFRlc3RGbGFncy5iOwoJZm9yZWFjaCAoIGU7IFRlc3RGbGFncyApIHsKCQlh c3NlcnQobyAmIGUpOwoJfQoJZm9yZWFjaCAoIGksIGU7IFRlc3RGbGFncyApIHsK CQlhc3NlcnQobyAmIGUpOwoJfQp9Cgp2b2lkIG1haW4oICkge30= ------------5uSTsBe9rureIZClGe1vta--
Jan 27 2012