// Copyright 2010 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 runtime
#include "runtime.h"
#include "go-type.h"
#include "interface.h"

typedef struct __go_type_descriptor descriptor;
typedef const struct __go_type_descriptor const_descriptor;
typedef struct __go_interface interface;
typedef struct __go_empty_interface empty_interface;

// Compare two type descriptors.
func ifacetypeeq(a *descriptor, b *descriptor) (eq bool) {
	eq = __go_type_descriptors_equal(a, b);
}

// Return the descriptor for an empty interface type.n
func efacetype(e empty_interface) (d *const_descriptor) {
	return e.__type_descriptor;
}

// Return the descriptor for a non-empty interface type.
func ifacetype(i interface) (d *const_descriptor) {
	if (i.__methods == nil) {
		return nil;
	}
	d = i.__methods[0];
}

// Convert an empty interface to an empty interface.
func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		runtime_panicstring("invalid interface value");
	ret = e;
	ok = ret.__type_descriptor != nil;
}

// Convert a non-empty interface to an empty interface.
func ifaceI2E2(i interface) (ret empty_interface, ok bool) {
	if (i.__methods == nil) {
		ret.__type_descriptor = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__type_descriptor = i.__methods[0];
		ret.__object = i.__object;
		ok = 1;
	}
}

// Convert an empty interface to a non-empty interface.
func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		runtime_panicstring("invalid interface value");
	if (e.__type_descriptor == nil) {
		ret.__methods = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__methods = __go_convert_interface_2(inter,
							 e.__type_descriptor,
							 1);
		ret.__object = e.__object;
		ok = ret.__methods != nil;
	}
}

// Convert a non-empty interface to a non-empty interface.
func ifaceI2I2(inter *descriptor, i interface) (ret interface, ok bool) {
	if (i.__methods == nil) {
		ret.__methods = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__methods = __go_convert_interface_2(inter,
							 i.__methods[0], 1);
		ret.__object = i.__object;
		ok = ret.__methods != nil;
	}
}

// Convert an empty interface to a pointer type.
func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		runtime_panicstring("invalid interface value");
	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
		ret = nil;
		ok = 0;
	} else {
		ret = e.__object;
		ok = 1;
	}
}

// Convert a non-empty interface to a pointer type.
func ifaceI2T2P(inter *descriptor, i interface) (ret *void, ok bool) {
	if (i.__methods == nil
	    || !__go_type_descriptors_equal(inter, i.__methods[0])) {
		ret = nil;
		ok = 0;
	} else {
		ret = i.__object;
		ok = 1;
	}
}

// Convert an empty interface to a non-pointer type.
func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		runtime_panicstring("invalid interface value");
	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
		__builtin_memset(ret, 0, inter->__size);
		ok = 0;
	} else {
		__builtin_memcpy(ret, e.__object, inter->__size);
		ok = 1;
	}
}

// Convert a non-empty interface to a non-pointer type.
func ifaceI2T2(inter *descriptor, i interface, ret *void) (ok bool) {
	if (i.__methods == nil
	    || !__go_type_descriptors_equal(inter, i.__methods[0])) {
		__builtin_memset(ret, 0, inter->__size);
		ok = 0;
	} else {
		__builtin_memcpy(ret, i.__object, inter->__size);
		ok = 1;
	}
}

// Return whether we can convert an interface to a type.
func ifaceI2Tp(to *descriptor, from *descriptor) (ok bool) {
	ok = __go_can_convert_to_interface(to, from);
}
