// 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 new_structs_S
func new_structs_S() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(structs.S)))
}

//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 new_structs_S2
func new_structs_S2() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(structs.S2)))
}

//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
	var _param_s *structs.S
	if _param_s_ref := _seq.FromRefNum(int32(param_s)); _param_s_ref != nil {
		_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
	var _param_s *structs.S
	if _param_s_ref := _seq.FromRefNum(int32(param_s)); _param_s_ref != nil {
		_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
}
