// Objective-C API for talking to structs Go package.
//   gobind -lang=objc structs
//
// File is generated by gobind. Do not edit.

#include <Foundation/Foundation.h>
#include "seq.h"
#include "_cgo_export.h"
#include "Structs.objc.h"


@implementation StructsS {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (instancetype)init {
	self = [super init];
	if (self) {
		__ref = go_seq_from_refnum(new_structs_S());
	}
	return self;
}

- (double)x {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_X_Get(refnum);
	double _r0 = (double)r0;
	return _r0;
}

- (void)setX:(double)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double _v = (double)v;
	proxystructs_S_X_Set(refnum, _v);
}

- (double)y {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_Y_Get(refnum);
	double _r0 = (double)r0;
	return _r0;
}

- (void)setY:(double)v {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double _v = (double)v;
	proxystructs_S_Y_Set(refnum, _v);
}

- (StructsS*)identity:(NSError**)error {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	struct proxystructs_S_Identity_return res = proxystructs_S_Identity(refnum);
	StructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(res.r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[StructsS alloc] initWithRef:_ret0__ref];
		}
	}
	Universeerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(res.r1);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[Universeerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	if (_error != nil) {
		return nil;
	}
	return _ret0_;
}

- (double)sum {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	double r0 = proxystructs_S_Sum(refnum);
	double _ret0_ = (double)r0;
	return _ret0_;
}

@end



@implementation StructsS2 {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (instancetype)init {
	self = [super init];
	if (self) {
		__ref = go_seq_from_refnum(new_structs_S2());
	}
	return self;
}

- (void)m {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxystructs_S2_M(refnum);
}

- (NSString*)string {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	nstring r0 = proxystructs_S2_String(refnum);
	NSString *_ret0_ = go_seq_to_objc_string(r0);
	return _ret0_;
}

@end


@implementation StructsI {
}

- (instancetype)initWithRef:(id)ref {
	self = [super init];
	if (self) { __ref = ref; }
	return self;
}

- (void)m {
	int32_t refnum = go_seq_go_to_refnum(self._ref);
	proxystructs_I_M(refnum);
}

@end



StructsS* StructsIdentity(StructsS* s) {
	int32_t _s;
	if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		_s = go_seq_go_to_refnum(s_proxy._ref);
	} else {
		_s = go_seq_to_refnum(s);
	}
	int32_t r0 = proxystructs__Identity(_s);
	StructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[StructsS alloc] initWithRef:_ret0__ref];
		}
	}
	return _ret0_;
}

StructsS* StructsIdentityWithError(StructsS* s, NSError** error) {
	int32_t _s;
	if ([s conformsToProtocol:@protocol(goSeqRefInterface)]) {
		id<goSeqRefInterface> s_proxy = (id<goSeqRefInterface>)(s);
		_s = go_seq_go_to_refnum(s_proxy._ref);
	} else {
		_s = go_seq_to_refnum(s);
	}
	struct proxystructs__IdentityWithError_return res = proxystructs__IdentityWithError(_s);
	StructsS* _ret0_ = nil;
	GoSeqRef* _ret0__ref = go_seq_from_refnum(res.r0);
	if (_ret0__ref != NULL) {
		_ret0_ = _ret0__ref.obj;
		if (_ret0_ == nil) {
			_ret0_ = [[StructsS alloc] initWithRef:_ret0__ref];
		}
	}
	Universeerror* _error = nil;
	GoSeqRef* _error_ref = go_seq_from_refnum(res.r1);
	if (_error_ref != NULL) {
		_error = _error_ref.obj;
		if (_error == nil) {
			_error = [[Universeerror alloc] initWithRef:_error_ref];
		}
	}
	if (_error != nil && error != nil) {
		*error = _error;
	}
	if (_error != nil) {
		return nil;
	}
	return _ret0_;
}

void cproxystructs_I_M(int32_t refnum) {
	@autoreleasepool {
		StructsI* o = go_seq_objc_from_refnum(refnum);
		[o m];
	}
}

__attribute__((constructor)) static void init() {
	init_seq();
}
