// Code generated by gobind. DO NOT EDIT.

// Package main is an autogenerated binder stub for package structs.
//
//   autogenerated by gobind -lang=go structs
package main

/*
#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_Structs_M
func proxystructs_Structs_M(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*structs.Structs)
	v.M()
}

//export new_structs_Structs
func new_structs_Structs() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(structs.Structs)))
}

//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
}
