// Code generated by gobind. DO NOT EDIT.

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

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

*/
import "C"

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

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

//export new_doc_NoDoc
func new_doc_NoDoc() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.NoDoc)))
}

//export proxydoc_S_SF_Set
func proxydoc_S_SF_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).SF = _v
}

//export proxydoc_S_SF_Get
func proxydoc_S_SF_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).SF
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_S2_Set
func proxydoc_S_S2_Set(refnum C.int32_t, v C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	// Must be a Go object
	var _v *doc.S2
	if _v_ref := _seq.FromRefNum(int32(v)); _v_ref != nil {
		_v = _v_ref.Get().(*doc.S2)
	}
	ref.Get().(*doc.S).S2 = _v
}

//export proxydoc_S_S2_Get
func proxydoc_S_S2_Get(refnum C.int32_t) C.int32_t {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).S2
	var _v C.int32_t = _seq.NullRefNum
	if v != nil {
		_v = C.int32_t(_seq.ToRefNum(v))
	}
	return _v
}

//export proxydoc_S_F1_Set
func proxydoc_S_F1_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).F1 = _v
}

//export proxydoc_S_F1_Get
func proxydoc_S_F1_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).F1
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_F2_Set
func proxydoc_S_F2_Set(refnum C.int32_t, v C.nstring) {
	ref := _seq.FromRefNum(int32(refnum))
	_v := decodeString(v)
	ref.Get().(*doc.S).F2 = _v
}

//export proxydoc_S_F2_Get
func proxydoc_S_F2_Get(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S).F2
	_v := encodeString(v)
	return _v
}

//export proxydoc_S_After
func proxydoc_S_After(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S)
	v.After()
}

//export proxydoc_S_Before
func proxydoc_S_Before(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(*doc.S)
	v.Before()
}

//export new_doc_S
func new_doc_S() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.S)))
}

//export new_doc_S2
func new_doc_S2() C.int32_t {
	return C.int32_t(_seq.ToRefNum(new(doc.S2)))
}

//export proxydoc_I_IM
func proxydoc_I_IM(refnum C.int32_t) {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(doc.I)
	v.IM()
}

type proxydoc_I _seq.Ref

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

func (p *proxydoc_I) IM() {
	C.cproxydoc_I_IM(C.int32_t(p.Bind_proxy_refnum__()))
}

//export var_setdoc_NoDocVar
func var_setdoc_NoDocVar(v C.double) {
	_v := float64(v)
	doc.NoDocVar = _v
}

//export var_getdoc_NoDocVar
func var_getdoc_NoDocVar() C.double {
	v := doc.NoDocVar
	_v := C.double(v)
	return _v
}

//export var_setdoc_Specific
func var_setdoc_Specific(v C.nstring) {
	_v := decodeString(v)
	doc.Specific = _v
}

//export var_getdoc_Specific
func var_getdoc_Specific() C.nstring {
	v := doc.Specific
	_v := encodeString(v)
	return _v
}

//export var_setdoc_V
func var_setdoc_V(v C.nstring) {
	_v := decodeString(v)
	doc.V = _v
}

//export var_getdoc_V
func var_getdoc_V() C.nstring {
	v := doc.V
	_v := encodeString(v)
	return _v
}

//export proxydoc__F
func proxydoc__F() {
	doc.F()
}

//export proxydoc__NewS
func proxydoc__NewS() C.int32_t {
	res_0 := doc.NewS()
	var _res_0 C.int32_t = _seq.NullRefNum
	if res_0 != nil {
		_res_0 = C.int32_t(_seq.ToRefNum(res_0))
	}
	return _res_0
}
