package jsoniter

import (
	
	
)

func decoderOfOptional( *ctx,  reflect2.Type) ValDecoder {
	 := .(*reflect2.UnsafePtrType)
	 := .Elem()
	 := decoderOfType(, )
	return &OptionalDecoder{, }
}

func encoderOfOptional( *ctx,  reflect2.Type) ValEncoder {
	 := .(*reflect2.UnsafePtrType)
	 := .Elem()
	 := encoderOfType(, )
	 := &OptionalEncoder{}
	return 
}

type OptionalDecoder struct {
	ValueType    reflect2.Type
	ValueDecoder ValDecoder
}

func ( *OptionalDecoder) ( unsafe.Pointer,  *Iterator) {
	if .ReadNil() {
		*((*unsafe.Pointer)()) = nil
	} else {
		if *((*unsafe.Pointer)()) == nil {
			//pointer to null, we have to allocate memory to hold the value
			 := .ValueType.UnsafeNew()
			.ValueDecoder.Decode(, )
			*((*unsafe.Pointer)()) = 
		} else {
			//reuse existing instance
			.ValueDecoder.Decode(*((*unsafe.Pointer)()), )
		}
	}
}

type dereferenceDecoder struct {
	// only to deference a pointer
	valueType    reflect2.Type
	valueDecoder ValDecoder
}

func ( *dereferenceDecoder) ( unsafe.Pointer,  *Iterator) {
	if *((*unsafe.Pointer)()) == nil {
		//pointer to null, we have to allocate memory to hold the value
		 := .valueType.UnsafeNew()
		.valueDecoder.Decode(, )
		*((*unsafe.Pointer)()) = 
	} else {
		//reuse existing instance
		.valueDecoder.Decode(*((*unsafe.Pointer)()), )
	}
}

type OptionalEncoder struct {
	ValueEncoder ValEncoder
}

func ( *OptionalEncoder) ( unsafe.Pointer,  *Stream) {
	if *((*unsafe.Pointer)()) == nil {
		.WriteNil()
	} else {
		.ValueEncoder.Encode(*((*unsafe.Pointer)()), )
	}
}

func ( *OptionalEncoder) ( unsafe.Pointer) bool {
	return *((*unsafe.Pointer)()) == nil
}

type dereferenceEncoder struct {
	ValueEncoder ValEncoder
}

func ( *dereferenceEncoder) ( unsafe.Pointer,  *Stream) {
	if *((*unsafe.Pointer)()) == nil {
		.WriteNil()
	} else {
		.ValueEncoder.Encode(*((*unsafe.Pointer)()), )
	}
}

func ( *dereferenceEncoder) ( unsafe.Pointer) bool {
	 := *((*unsafe.Pointer)())
	if  == nil {
		return true
	}
	return .ValueEncoder.IsEmpty()
}

func ( *dereferenceEncoder) ( unsafe.Pointer) bool {
	 := *((*unsafe.Pointer)())
	if  == nil {
		return true
	}
	,  := .ValueEncoder.(IsEmbeddedPtrNil)
	if ! {
		return false
	}
	 := unsafe.Pointer()
	return .IsEmbeddedPtrNil()
}

type referenceEncoder struct {
	encoder ValEncoder
}

func ( *referenceEncoder) ( unsafe.Pointer,  *Stream) {
	.encoder.Encode(unsafe.Pointer(&), )
}

func ( *referenceEncoder) ( unsafe.Pointer) bool {
	return .encoder.IsEmpty(unsafe.Pointer(&))
}

type referenceDecoder struct {
	decoder ValDecoder
}

func ( *referenceDecoder) ( unsafe.Pointer,  *Iterator) {
	.decoder.Decode(unsafe.Pointer(&), )
}