mirror of
https://github.com/golang/go
synced 2024-11-25 07:17:56 -07:00
implement new restrictions on what
can be compared/hashed. R=r DELTA=351 (201 added, 80 deleted, 70 changed) OCL=23423 CL=23481
This commit is contained in:
parent
18b05c1a8d
commit
a7f6d4066e
@ -37,13 +37,12 @@ enum
|
|||||||
PRIME10 = 10093,
|
PRIME10 = 10093,
|
||||||
|
|
||||||
AUNK = 100,
|
AUNK = 100,
|
||||||
|
|
||||||
// these values are known by runtime
|
// these values are known by runtime
|
||||||
ASIMP = 0,
|
AMEM = 0,
|
||||||
|
ANOEQ,
|
||||||
ASTRING,
|
ASTRING,
|
||||||
APTR,
|
|
||||||
AINTER,
|
AINTER,
|
||||||
ASLICE,
|
|
||||||
ASTRUCT,
|
|
||||||
|
|
||||||
BADWIDTH = -1000000000
|
BADWIDTH = -1000000000
|
||||||
};
|
};
|
||||||
|
@ -291,26 +291,16 @@ algtype(Type *t)
|
|||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
a = AUNK;
|
if(issimple[t->etype] || isptr[t->etype] || t->etype == TCHAN)
|
||||||
if(issimple[t->etype])
|
a = AMEM; // just bytes (int, ptr, etc)
|
||||||
a = ASIMP; // simple mem
|
|
||||||
else
|
else
|
||||||
if(t->etype == TSTRING)
|
if(t->etype == TSTRING)
|
||||||
a = ASTRING; // string
|
a = ASTRING; // string
|
||||||
else
|
else
|
||||||
if(isptr[simtype[t->etype]])
|
if(t->etype == TINTER)
|
||||||
a = APTR; // pointer
|
|
||||||
else
|
|
||||||
if(isslice(t))
|
|
||||||
a = ASLICE;
|
|
||||||
else
|
|
||||||
if(t->etype == TSTRUCT)
|
|
||||||
a = ASTRUCT;
|
|
||||||
else
|
|
||||||
if(isinter(t))
|
|
||||||
a = AINTER; // interface
|
a = AINTER; // interface
|
||||||
// else
|
else
|
||||||
// fatal("algtype: cant find type %T", t);
|
a = ANOEQ; // just bytes, but no hash/eq
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,17 +88,9 @@ sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
|
|||||||
Hchan *c;
|
Hchan *c;
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
switch(elemalg){
|
if(elemalg >= nelem(algarray)) {
|
||||||
case ASIMP:
|
|
||||||
case ASTRING:
|
|
||||||
case APTR:
|
|
||||||
case AINTER:
|
|
||||||
case AARRAY:
|
|
||||||
case ASTRUCT:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("chan(alg=%d)\n", elemalg);
|
printf("chan(alg=%d)\n", elemalg);
|
||||||
throw("sys·newchan: unsupported channel element type");
|
throw("sys·newchan: unsupported elem type");
|
||||||
}
|
}
|
||||||
|
|
||||||
c = mal(sizeof(*c));
|
c = mal(sizeof(*c));
|
||||||
|
@ -663,28 +663,12 @@ sys·newmap(uint32 keysize, uint32 valsize,
|
|||||||
{
|
{
|
||||||
Hmap *h;
|
Hmap *h;
|
||||||
|
|
||||||
switch(keyalg) {
|
if(keyalg >= nelem(algarray) || algarray[keyalg].hash == nohash) {
|
||||||
case ASIMP:
|
|
||||||
case ASTRING:
|
|
||||||
case APTR:
|
|
||||||
case AINTER:
|
|
||||||
case AARRAY:
|
|
||||||
case ASTRUCT:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("map(keyalg=%d)\n", keyalg);
|
printf("map(keyalg=%d)\n", keyalg);
|
||||||
throw("sys·newmap: unsupported map key type");
|
throw("sys·newmap: unsupported map key type");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(valalg) {
|
if(valalg >= nelem(algarray)) {
|
||||||
case ASIMP:
|
|
||||||
case ASTRING:
|
|
||||||
case APTR:
|
|
||||||
case AINTER:
|
|
||||||
case AARRAY:
|
|
||||||
case ASTRUCT:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("map(valalg=%d)\n", valalg);
|
printf("map(valalg=%d)\n", valalg);
|
||||||
throw("sys·newmap: unsupported map value type");
|
throw("sys·newmap: unsupported map value type");
|
||||||
}
|
}
|
||||||
|
@ -404,11 +404,32 @@ sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok)
|
|||||||
FLUSH(&ok);
|
FLUSH(&ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ifaceeq(i1 any, i2 any) (ret bool);
|
uint64
|
||||||
void
|
ifacehash(Iface a)
|
||||||
sys·ifaceeq(Iface i1, Iface i2, bool ret)
|
|
||||||
{
|
{
|
||||||
int32 alg, wid;
|
int32 alg, wid;
|
||||||
|
|
||||||
|
if(a.type == nil)
|
||||||
|
return 0;
|
||||||
|
alg = a.type->sigt->hash;
|
||||||
|
wid = a.type->sigt->offset;
|
||||||
|
if(algarray[alg].hash == nohash) {
|
||||||
|
// calling nohash will throw too,
|
||||||
|
// but we can print a better error.
|
||||||
|
printf("hash of unhashable type %s\n", a.type->sigt->name);
|
||||||
|
throw("interface hash");
|
||||||
|
}
|
||||||
|
if(wid <= sizeof a.data)
|
||||||
|
return algarray[alg].hash(wid, &a.data);
|
||||||
|
else
|
||||||
|
return algarray[alg].hash(wid, a.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ifaceeq(Iface i1, Iface i2)
|
||||||
|
{
|
||||||
|
int32 alg, wid;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
if(iface_debug) {
|
if(iface_debug) {
|
||||||
prints("Ieq i1=");
|
prints("Ieq i1=");
|
||||||
@ -438,6 +459,13 @@ sys·ifaceeq(Iface i1, Iface i2, bool ret)
|
|||||||
if(wid != i2.type->sigt->offset)
|
if(wid != i2.type->sigt->offset)
|
||||||
goto no;
|
goto no;
|
||||||
|
|
||||||
|
if(algarray[alg].equal == noequal) {
|
||||||
|
// calling noequal will throw too,
|
||||||
|
// but we can print a better error.
|
||||||
|
printf("comparing uncomparable type %s\n", i1.type->sigt->name);
|
||||||
|
throw("interface compare");
|
||||||
|
}
|
||||||
|
|
||||||
if(wid <= sizeof i1.data) {
|
if(wid <= sizeof i1.data) {
|
||||||
if(!algarray[alg].equal(wid, &i1.data, &i2.data))
|
if(!algarray[alg].equal(wid, &i1.data, &i2.data))
|
||||||
goto no;
|
goto no;
|
||||||
@ -454,6 +482,14 @@ no:
|
|||||||
sys·printbool(ret);
|
sys·printbool(ret);
|
||||||
prints("\n");
|
prints("\n");
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ifaceeq(i1 any, i2 any) (ret bool);
|
||||||
|
void
|
||||||
|
sys·ifaceeq(Iface i1, Iface i2, bool ret)
|
||||||
|
{
|
||||||
|
ret = ifaceeq(i1, i2);
|
||||||
FLUSH(&ret);
|
FLUSH(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +562,7 @@ fakesigt(string type, bool indir)
|
|||||||
sigt = mal(2*sizeof sigt[0]);
|
sigt = mal(2*sizeof sigt[0]);
|
||||||
sigt[0].name = mal(type->len + 1);
|
sigt[0].name = mal(type->len + 1);
|
||||||
mcpy(sigt[0].name, type->str, type->len);
|
mcpy(sigt[0].name, type->str, type->len);
|
||||||
sigt[0].hash = ASIMP; // alg
|
sigt[0].hash = AMEM; // alg
|
||||||
if(indir)
|
if(indir)
|
||||||
sigt[0].offset = 2*sizeof(niliface.data); // big width
|
sigt[0].offset = 2*sizeof(niliface.data); // big width
|
||||||
else
|
else
|
||||||
|
@ -328,57 +328,52 @@ strprint(uint32 s, string *a)
|
|||||||
sys·printstring(*a);
|
sys·printstring(*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static uint64
|
||||||
strcopy(uint32 s, string *a, string *b)
|
interhash(uint32 s, Iface *a)
|
||||||
{
|
{
|
||||||
USED(s);
|
USED(s);
|
||||||
if(b == nil) {
|
return ifacehash(*a);
|
||||||
*a = nil;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*a = *b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64
|
static void
|
||||||
ptrhash(uint32 s, void **a)
|
interprint(uint32 s, Iface *a)
|
||||||
{
|
{
|
||||||
return memhash(s, *a);
|
USED(s);
|
||||||
|
sys·printinter(*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32
|
static uint32
|
||||||
ptrequal(uint32 s, void **a, void **b)
|
interequal(uint32 s, Iface *a, Iface *b)
|
||||||
{
|
{
|
||||||
USED(s, a, b);
|
USED(s);
|
||||||
prints("ptrequal\n");
|
return ifaceeq(*a, *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64
|
||||||
|
nohash(uint32 s, void *a)
|
||||||
|
{
|
||||||
|
USED(s);
|
||||||
|
USED(a);
|
||||||
|
throw("hash of unhashable type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
uint32
|
||||||
ptrprint(uint32 s, void **a)
|
noequal(uint32 s, void *a, void *b)
|
||||||
{
|
|
||||||
USED(s, a);
|
|
||||||
prints("ptrprint\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ptrcopy(uint32 s, void **a, void **b)
|
|
||||||
{
|
{
|
||||||
USED(s);
|
USED(s);
|
||||||
if(b == nil) {
|
USED(a);
|
||||||
*a = nil;
|
USED(b);
|
||||||
return;
|
throw("comparing uncomparable types");
|
||||||
}
|
return 0;
|
||||||
*a = *b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Alg
|
Alg
|
||||||
algarray[] =
|
algarray[] =
|
||||||
{
|
{
|
||||||
[ASIMP] { memhash, memequal, memprint, memcopy },
|
[AMEM] { memhash, memequal, memprint, memcopy },
|
||||||
[ASTRING] { strhash, strequal, strprint, strcopy },
|
[ANOEQ] { nohash, noequal, memprint, memcopy },
|
||||||
[APTR] { memhash, memequal, memprint, memcopy }, // TODO: ptr routines
|
[ASTRING] { strhash, strequal, strprint, memcopy },
|
||||||
[AINTER] { memhash, memequal, memprint, memcopy }, // TODO: interface routines
|
[AINTER] { interhash, interequal, interprint, memcopy },
|
||||||
[ASTRUCT] { memhash, memequal, memprint, memcopy }, // TODO: what goes here?
|
|
||||||
[AARRAY] { memhash, memequal, memprint, memcopy }, // TODO: what goes here?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,18 +226,17 @@ struct Func
|
|||||||
*/
|
*/
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ASIMP = 0,
|
AMEM,
|
||||||
|
ANOEQ,
|
||||||
ASTRING,
|
ASTRING,
|
||||||
APTR,
|
|
||||||
AINTER,
|
AINTER,
|
||||||
AARRAY,
|
Amax
|
||||||
ASTRUCT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* external data
|
* external data
|
||||||
*/
|
*/
|
||||||
extern Alg algarray[];
|
extern Alg algarray[Amax];
|
||||||
extern string emptystring;
|
extern string emptystring;
|
||||||
G* allg;
|
G* allg;
|
||||||
int32 goidgen;
|
int32 goidgen;
|
||||||
@ -299,6 +298,10 @@ void* stackalloc(uint32);
|
|||||||
void stackfree(void*);
|
void stackfree(void*);
|
||||||
MCache* allocmcache(void);
|
MCache* allocmcache(void);
|
||||||
void mallocinit(void);
|
void mallocinit(void);
|
||||||
|
bool ifaceeq(Iface, Iface);
|
||||||
|
uint64 ifacehash(Iface);
|
||||||
|
uint64 nohash(uint32, void*);
|
||||||
|
uint32 noequal(uint32, void*, void*);
|
||||||
|
|
||||||
#pragma varargck argpos printf 1
|
#pragma varargck argpos printf 1
|
||||||
|
|
||||||
@ -366,6 +369,7 @@ void notewakeup(Note*);
|
|||||||
#define sys_printfloat sys·printfloat
|
#define sys_printfloat sys·printfloat
|
||||||
#define sys_printhex sys·printhex
|
#define sys_printhex sys·printhex
|
||||||
#define sys_printint sys·printint
|
#define sys_printint sys·printint
|
||||||
|
#define sys_printinter sys·printinter
|
||||||
#define sys_printpc sys·printpc
|
#define sys_printpc sys·printpc
|
||||||
#define sys_printpointer sys·printpointer
|
#define sys_printpointer sys·printpointer
|
||||||
#define sys_printstring sys·printstring
|
#define sys_printstring sys·printstring
|
||||||
@ -393,6 +397,7 @@ void* sys_getcallerpc(void*);
|
|||||||
void sys_printbool(bool);
|
void sys_printbool(bool);
|
||||||
void sys_printfloat(float64);
|
void sys_printfloat(float64);
|
||||||
void sys_printint(int64);
|
void sys_printint(int64);
|
||||||
|
void sys_printinter(Iface);
|
||||||
void sys_printstring(string);
|
void sys_printstring(string);
|
||||||
void sys_printpc(void*);
|
void sys_printpc(void*);
|
||||||
void sys_printpointer(void*);
|
void sys_printpointer(void*);
|
||||||
|
@ -62,25 +62,6 @@ func maptest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mt1 = make(map[T]int)
|
|
||||||
var ma1 = make(map[[]int] int)
|
|
||||||
|
|
||||||
func maptest2() {
|
|
||||||
mt1[t] = 123;
|
|
||||||
t1 := t;
|
|
||||||
val, ok := mt1[t1];
|
|
||||||
if val != 123 || !ok {
|
|
||||||
println("fail: map key struct", val, ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
ma1[a] = 345;
|
|
||||||
a1 := a;
|
|
||||||
val, ok = ma1[a1];
|
|
||||||
if val != 345 || !ok {
|
|
||||||
panic("map key array", val, ok);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ct = make(chan T)
|
var ct = make(chan T)
|
||||||
var ca = make(chan []int)
|
var ca = make(chan []int)
|
||||||
|
|
||||||
@ -136,7 +117,6 @@ func interfacetest() {
|
|||||||
func main() {
|
func main() {
|
||||||
arraycmptest();
|
arraycmptest();
|
||||||
maptest();
|
maptest();
|
||||||
maptest2();
|
|
||||||
chantest();
|
chantest();
|
||||||
interfacetest();
|
interfacetest();
|
||||||
}
|
}
|
||||||
|
66
test/cmp1.go
Normal file
66
test/cmp1.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func use(bool) { }
|
||||||
|
|
||||||
|
func stringptr(s string) uintptr {
|
||||||
|
return *(&s).(unsafe.Pointer).(*uintptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
func isfalse(b bool) {
|
||||||
|
if b { panicln("wanted false, got true") } // stack will explain where
|
||||||
|
}
|
||||||
|
|
||||||
|
func istrue(b bool) {
|
||||||
|
if !b { panicln("wanted true, got false") } // stack will explain where
|
||||||
|
}
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
var a []int;
|
||||||
|
var b map[string]int;
|
||||||
|
|
||||||
|
var c string = "hello";
|
||||||
|
var d string = "hel"; // try to get different pointer
|
||||||
|
d = d + "lo";
|
||||||
|
if stringptr(c) == stringptr(d) {
|
||||||
|
panic("compiler too smart -- got same string")
|
||||||
|
}
|
||||||
|
|
||||||
|
var e = make(chan int);
|
||||||
|
|
||||||
|
var ia interface{} = a;
|
||||||
|
var ib interface{} = b;
|
||||||
|
var ic interface{} = c;
|
||||||
|
var id interface{} = d;
|
||||||
|
var ie interface{} = e;
|
||||||
|
|
||||||
|
// these comparisons are okay because
|
||||||
|
// string compare is okay and the others
|
||||||
|
// are comparisons where the types differ.
|
||||||
|
isfalse(ia == ib);
|
||||||
|
isfalse(ia == ic);
|
||||||
|
isfalse(ia == id);
|
||||||
|
isfalse(ib == ic);
|
||||||
|
isfalse(ib == id);
|
||||||
|
istrue(ic == id);
|
||||||
|
istrue(ie == ie);
|
||||||
|
|
||||||
|
// map of interface should use == on interface values,
|
||||||
|
// not memory.
|
||||||
|
// TODO: should m[c], m[d] be valid here?
|
||||||
|
var m = make(map[interface{}] int);
|
||||||
|
m[ic] = 1;
|
||||||
|
m[id] = 2;
|
||||||
|
if m[ic] != 2 {
|
||||||
|
panic("m[ic] = ", m[ic]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
16
test/cmp2.go
Normal file
16
test/cmp2.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ! ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func use(bool) { }
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
var a []int;
|
||||||
|
var ia interface{} = a;
|
||||||
|
use(ia == ia);
|
||||||
|
}
|
16
test/cmp3.go
Normal file
16
test/cmp3.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ! ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func use(bool) { }
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
var b map[string]int;
|
||||||
|
var ib interface{} = b;
|
||||||
|
use(ib == ib);
|
||||||
|
}
|
15
test/cmp4.go
Normal file
15
test/cmp4.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ! ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
var a []int;
|
||||||
|
var ia interface{} = a;
|
||||||
|
var m = make(map[interface{}] int);
|
||||||
|
m[ia] = 1;
|
||||||
|
}
|
15
test/cmp5.go
Normal file
15
test/cmp5.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ! ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
var b map[string]int;
|
||||||
|
var ib interface{} = b;
|
||||||
|
var m = make(map[interface{}] int);
|
||||||
|
m[ib] = 1;
|
||||||
|
}
|
@ -1,4 +1,36 @@
|
|||||||
|
|
||||||
|
=========== ./cmp2.go
|
||||||
|
comparing uncomparable type []int
|
||||||
|
throw: interface compare
|
||||||
|
SIGSEGV: segmentation violation
|
||||||
|
Faulting address: 0x0
|
||||||
|
pc: xxx
|
||||||
|
|
||||||
|
|
||||||
|
=========== ./cmp3.go
|
||||||
|
comparing uncomparable type map[string] int
|
||||||
|
throw: interface compare
|
||||||
|
SIGSEGV: segmentation violation
|
||||||
|
Faulting address: 0x0
|
||||||
|
pc: xxx
|
||||||
|
|
||||||
|
|
||||||
|
=========== ./cmp4.go
|
||||||
|
hash of unhashable type []int
|
||||||
|
throw: interface hash
|
||||||
|
SIGSEGV: segmentation violation
|
||||||
|
Faulting address: 0x0
|
||||||
|
pc: xxx
|
||||||
|
|
||||||
|
|
||||||
|
=========== ./cmp5.go
|
||||||
|
hash of unhashable type map[string] int
|
||||||
|
throw: interface hash
|
||||||
|
SIGSEGV: segmentation violation
|
||||||
|
Faulting address: 0x0
|
||||||
|
pc: xxx
|
||||||
|
|
||||||
|
|
||||||
=========== ./convlit.go
|
=========== ./convlit.go
|
||||||
BUG: errchk: ./convlit.go: missing expected error message on line 16: 'conver|incompatible'
|
BUG: errchk: ./convlit.go: missing expected error message on line 16: 'conver|incompatible'
|
||||||
errchk: ./convlit.go: missing expected error message on line 22: 'convert'
|
errchk: ./convlit.go: missing expected error message on line 22: 'convert'
|
||||||
|
68
test/map.go
68
test/map.go
@ -52,7 +52,7 @@ func main() {
|
|||||||
mipT := make(map[int] *T);
|
mipT := make(map[int] *T);
|
||||||
mpTi := make(map[*T] int);
|
mpTi := make(map[*T] int);
|
||||||
mit := make(map[int] T);
|
mit := make(map[int] T);
|
||||||
mti := make(map[T] int);
|
// mti := make(map[T] int);
|
||||||
|
|
||||||
type M map[int] int;
|
type M map[int] int;
|
||||||
mipM := make(map[int] M);
|
mipM := make(map[int] M);
|
||||||
@ -88,7 +88,7 @@ func main() {
|
|||||||
mpTi[apT[i]] = i;
|
mpTi[apT[i]] = i;
|
||||||
mipM[i] = m;
|
mipM[i] = m;
|
||||||
mit[i] = t;
|
mit[i] = t;
|
||||||
mti[t] = i;
|
// mti[t] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test len
|
// test len
|
||||||
@ -122,15 +122,15 @@ func main() {
|
|||||||
if len(mpTi) != count {
|
if len(mpTi) != count {
|
||||||
fmt.Printf("len(mpTi) = %d\n", len(mpTi));
|
fmt.Printf("len(mpTi) = %d\n", len(mpTi));
|
||||||
}
|
}
|
||||||
if len(mti) != count {
|
// if len(mti) != count {
|
||||||
fmt.Printf("len(mti) = %d\n", len(mti));
|
// fmt.Printf("len(mti) = %d\n", len(mti));
|
||||||
}
|
// }
|
||||||
if len(mipM) != count {
|
if len(mipM) != count {
|
||||||
fmt.Printf("len(mipM) = %d\n", len(mipM));
|
fmt.Printf("len(mipM) = %d\n", len(mipM));
|
||||||
}
|
}
|
||||||
if len(mti) != count {
|
// if len(mti) != count {
|
||||||
fmt.Printf("len(mti) = %d\n", len(mti));
|
// fmt.Printf("len(mti) = %d\n", len(mti));
|
||||||
}
|
// }
|
||||||
if len(mit) != count {
|
if len(mit) != count {
|
||||||
fmt.Printf("len(mit) = %d\n", len(mit));
|
fmt.Printf("len(mit) = %d\n", len(mit));
|
||||||
}
|
}
|
||||||
@ -174,15 +174,15 @@ func main() {
|
|||||||
if(mpTi[apT[i]] != i) {
|
if(mpTi[apT[i]] != i) {
|
||||||
fmt.Printf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]]);
|
fmt.Printf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]]);
|
||||||
}
|
}
|
||||||
if(mti[t] != i) {
|
// if(mti[t] != i) {
|
||||||
fmt.Printf("mti[%s] = %s\n", s, mti[t]);
|
// fmt.Printf("mti[%s] = %s\n", s, mti[t]);
|
||||||
}
|
// }
|
||||||
if (mipM[i][i] != i + 1) {
|
if (mipM[i][i] != i + 1) {
|
||||||
fmt.Printf("mipM[%d][%d] = %d\n", i, i, mipM[i][i]);
|
fmt.Printf("mipM[%d][%d] = %d\n", i, i, mipM[i][i]);
|
||||||
}
|
}
|
||||||
if(mti[t] != i) {
|
// if(mti[t] != i) {
|
||||||
fmt.Printf("mti[%v] = %d\n", t, mti[t]);
|
// fmt.Printf("mti[%v] = %d\n", t, mti[t]);
|
||||||
}
|
// }
|
||||||
if(mit[i].i != int64(i) || mit[i].f != f) {
|
if(mit[i].i != int64(i) || mit[i].f != f) {
|
||||||
fmt.Printf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f);
|
fmt.Printf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f);
|
||||||
}
|
}
|
||||||
@ -314,16 +314,16 @@ func main() {
|
|||||||
fmt.Printf("tuple existence assign: mit[%d]\n", i);
|
fmt.Printf("tuple existence assign: mit[%d]\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
// {
|
||||||
a, b := mti[t];
|
// a, b := mti[t];
|
||||||
if !b {
|
// if !b {
|
||||||
fmt.Printf("tuple existence decl: mti[%d]\n", i);
|
// fmt.Printf("tuple existence decl: mti[%d]\n", i);
|
||||||
}
|
// }
|
||||||
a, b = mti[t];
|
// a, b = mti[t];
|
||||||
if !b {
|
// if !b {
|
||||||
fmt.Printf("tuple existence assign: mti[%d]\n", i);
|
// fmt.Printf("tuple existence assign: mti[%d]\n", i);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// test nonexistence with tuple check
|
// test nonexistence with tuple check
|
||||||
@ -442,16 +442,16 @@ func main() {
|
|||||||
fmt.Printf("tuple nonexistence assign: mipM[%d]", i);
|
fmt.Printf("tuple nonexistence assign: mipM[%d]", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
// {
|
||||||
a, b := mti[t];
|
// a, b := mti[t];
|
||||||
if b {
|
// if b {
|
||||||
fmt.Printf("tuple nonexistence decl: mti[%d]", i);
|
// fmt.Printf("tuple nonexistence decl: mti[%d]", i);
|
||||||
}
|
// }
|
||||||
a, b = mti[t];
|
// a, b = mti[t];
|
||||||
if b {
|
// if b {
|
||||||
fmt.Printf("tuple nonexistence assign: mti[%d]", i);
|
// fmt.Printf("tuple nonexistence assign: mti[%d]", i);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
{
|
{
|
||||||
a, b := mit[i];
|
a, b := mit[i];
|
||||||
if b {
|
if b {
|
||||||
|
Loading…
Reference in New Issue
Block a user