// Package gomobile_bind is an autogenerated binder stub for package structs.
//   gobind -lang=go structs
//
// File is generated by gobind. Do not edit.
package gomobile_bind

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "structs.h"

*/
import "C"

import (
	_seq "golang.org/x/mobile/bind/seq"
	"structs"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

//export proxystructs_S_X_Set
func proxystructs_S_X_Set(refnum C.int32_t, v C.double) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := float64(v)
	ref.Get().(*structs.S).X = _v
}

//export proxystructs_S_X_Get
func proxystructs_S_X_Get(refnum C.int32_t) C.double {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S).X
	_v := C.double(v)
	return _v
}

//export proxystructs_S_Y_Set
func proxystructs_S_Y_Set(refnum C.int32_t, v C.double) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := float64(v)
	ref.Get().(*structs.S).Y = _v
}

//export proxystructs_S_Y_Get
func proxystructs_S_Y_Get(refnum C.int32_t) C.double {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S).Y
	_v := C.double(v)
	return _v
}

//export proxystructs_S_Identity
func proxystructs_S_Identity(refnum C.int32_t) (C.int32_t, C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S)
	res_0, res_1 := v.Identity()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}

//export proxystructs_S_Sum
func proxystructs_S_Sum(refnum C.int32_t) C.double {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S)
	res_0 := v.Sum()
	_res_0 := C.double(res_0)
	return _res_0
}

//export proxystructs_S2_M
func proxystructs_S2_M(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S2)
	v.M()
}

//export proxystructs_S2_String
func proxystructs_S2_String(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.S2)
	res_0 := v.String()
	_res_0 := encodeString(res_0)
	return _res_0
}

//export proxystructs_I_M
func proxystructs_I_M(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(structs.I)
	v.M()
}

type proxystructs_I _seq.Ref

func (p *proxystructs_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxystructs_I) M() {
	C.cproxystructs_I_M(C.int32_t(p.Bind_proxy_refnum__()))
}

//export proxystructs__Identity
func proxystructs__Identity(param_s C.int32_t) C.int32_t {
	// Must be a Go object
	_param_s_ref := _seq.FromRefNum(int32(param_s))
	_param_s := _param_s_ref.Get().(*structs.S)
	res_0 := structs.Identity(_param_s)
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}

//export proxystructs__IdentityWithError
func proxystructs__IdentityWithError(param_s C.int32_t) (C.int32_t, C.int32_t) {
	// Must be a Go object
	_param_s_ref := _seq.FromRefNum(int32(param_s))
	_param_s := _param_s_ref.Get().(*structs.S)
	res_0, res_1 := structs.IdentityWithError(_param_s)
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	var _res_1 C.int32_t = _seq.NullRefNum
	if res_1 != nil {
		_res_1 = C.int32_t(_seq.ToRefNum(res_1))
	}
	return _res_0, _res_1
}
