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

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

- (nonnull 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* _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 {
}

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

- (nonnull 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 {
}

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

- (nonnull 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 {
}

- (nonnull 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* _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();
}
