// 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* _Nullable)identity:(NSError* _Nullable*)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* _Nonnull)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 StructsStructs {
}

- (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_Structs());
	}
	return self;
}

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

@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* _Nullable StructsIdentity(StructsS* _Nullable 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* _Nullable StructsIdentityWithError(StructsS* _Nullable s, NSError* _Nullable* 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();
}
