Dependencies for the affinity router and the
affinity routing daemon.

Change-Id: Icda72c3594ef7f8f0bc0c33dc03087a4c25529ca
diff --git a/vendor/github.com/ugorji/go/codec/0doc.go b/vendor/github.com/ugorji/go/codec/0doc.go
new file mode 100644
index 0000000..b61a818
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/0doc.go
@@ -0,0 +1,264 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+/*
+Package codec provides a
+High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
+for binc, msgpack, cbor, json.
+
+Supported Serialization formats are:
+
+  - msgpack: https://github.com/msgpack/msgpack
+  - binc:    http://github.com/ugorji/binc
+  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
+  - json:    http://json.org http://tools.ietf.org/html/rfc7159
+  - simple:
+
+To install:
+
+    go get github.com/ugorji/go/codec
+
+This package will carefully use 'unsafe' for performance reasons in specific places.
+You can build without unsafe use by passing the safe or appengine tag
+i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
+go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
+go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
+
+For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
+
+The idiomatic Go support is as seen in other encoding packages in
+the standard library (ie json, xml, gob, etc).
+
+Rich Feature Set includes:
+
+  - Simple but extremely powerful and feature-rich API
+  - Support for go1.4 and above, while selectively using newer APIs for later releases
+  - Excellent code coverage ( > 90% )
+  - Very High Performance.
+    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
+  - Careful selected use of 'unsafe' for targeted performance gains.
+    100% mode exists where 'unsafe' is not used at all.
+  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
+  - Coerce types where appropriate
+    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
+  - Corner Cases:
+    Overflows, nil maps/slices, nil values in streams are handled correctly
+  - Standard field renaming via tags
+  - Support for omitting empty fields during an encoding
+  - Encoding from any value and decoding into pointer to any value
+    (struct, slice, map, primitives, pointers, interface{}, etc)
+  - Extensions to support efficient encoding/decoding of any named types
+  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
+  - Support IsZero() bool to determine if a value is a zero value.
+    Analogous to time.Time.IsZero() bool.
+  - Decoding without a schema (into a interface{}).
+    Includes Options to configure what specific map or slice type to use
+    when decoding an encoded list or map into a nil interface{}
+  - Mapping a non-interface type to an interface, so we can decode appropriately
+    into any interface type with a correctly configured non-interface value.
+  - Encode a struct as an array, and decode struct from an array in the data stream
+  - Option to encode struct keys as numbers (instead of strings)
+    (to support structured streams with fields encoded as numeric codes)
+  - Comprehensive support for anonymous fields
+  - Fast (no-reflection) encoding/decoding of common maps and slices
+  - Code-generation for faster performance.
+  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
+  - Support indefinite-length formats to enable true streaming
+    (for formats which support it e.g. json, cbor)
+  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
+    This mostly applies to maps, where iteration order is non-deterministic.
+  - NIL in data stream decoded as zero value
+  - Never silently skip data when decoding.
+    User decides whether to return an error or silently skip data when keys or indexes
+    in the data stream do not map to fields in the struct.
+  - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown)
+  - Encode/Decode from/to chan types (for iterative streaming support)
+  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
+  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
+  - Handle unique idiosyncrasies of codecs e.g.
+    - For messagepack, configure how ambiguities in handling raw bytes are resolved
+    - For messagepack, provide rpc server/client codec to support
+      msgpack-rpc protocol defined at:
+      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
+
+Extension Support
+
+Users can register a function to handle the encoding or decoding of
+their custom types.
+
+There are no restrictions on what the custom type can be. Some examples:
+
+    type BisSet   []int
+    type BitSet64 uint64
+    type UUID     string
+    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
+    type GifImage struct { ... }
+
+As an illustration, MyStructWithUnexportedFields would normally be
+encoded as an empty map because it has no exported fields, while UUID
+would be encoded as a string. However, with extension support, you can
+encode any of these however you like.
+
+Custom Encoding and Decoding
+
+This package maintains symmetry in the encoding and decoding halfs.
+We determine how to encode or decode by walking this decision tree
+
+  - is type a codec.Selfer?
+  - is there an extension registered for the type?
+  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
+  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
+  - is format text-based, and type an encoding.TextMarshaler?
+  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
+
+This symmetry is important to reduce chances of issues happening because the
+encoding and decoding sides are out of sync e.g. decoded via very specific
+encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
+
+Consequently, if a type only defines one-half of the symmetry
+(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
+then that type doesn't satisfy the check and we will continue walking down the
+decision tree.
+
+RPC
+
+RPC Client and Server Codecs are implemented, so the codecs can be used
+with the standard net/rpc package.
+
+Usage
+
+The Handle is SAFE for concurrent READ, but NOT SAFE for concurrent modification.
+
+The Encoder and Decoder are NOT safe for concurrent use.
+
+Consequently, the usage model is basically:
+
+    - Create and initialize the Handle before any use.
+      Once created, DO NOT modify it.
+    - Multiple Encoders or Decoders can now use the Handle concurrently.
+      They only read information off the Handle (never write).
+    - However, each Encoder or Decoder MUST not be used concurrently
+    - To re-use an Encoder/Decoder, call Reset(...) on it first.
+      This allows you use state maintained on the Encoder/Decoder.
+
+Sample usage model:
+
+    // create and configure Handle
+    var (
+      bh codec.BincHandle
+      mh codec.MsgpackHandle
+      ch codec.CborHandle
+    )
+
+    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
+
+    // configure extensions
+    // e.g. for msgpack, define functions and enable Time support for tag 1
+    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
+
+    // create and use decoder/encoder
+    var (
+      r io.Reader
+      w io.Writer
+      b []byte
+      h = &bh // or mh to use msgpack
+    )
+
+    dec = codec.NewDecoder(r, h)
+    dec = codec.NewDecoderBytes(b, h)
+    err = dec.Decode(&v)
+
+    enc = codec.NewEncoder(w, h)
+    enc = codec.NewEncoderBytes(&b, h)
+    err = enc.Encode(v)
+
+    //RPC Server
+    go func() {
+        for {
+            conn, err := listener.Accept()
+            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
+            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
+            rpc.ServeCodec(rpcCodec)
+        }
+    }()
+
+    //RPC Communication (client side)
+    conn, err = net.Dial("tcp", "localhost:5555")
+    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
+    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
+    client := rpc.NewClientWithCodec(rpcCodec)
+
+Running Tests
+
+To run tests, use the following:
+
+    go test
+
+To run the full suite of tests, use the following:
+
+    go test -tags alltests -run Suite
+
+You can run the tag 'safe' to run tests or build in safe mode. e.g.
+
+    go test -tags safe -run Json
+    go test -tags "alltests safe" -run Suite
+
+Running Benchmarks
+
+Please see http://github.com/ugorji/go-codec-bench .
+
+Caveats
+
+Struct fields matching the following are ignored during encoding and decoding
+    - struct tag value set to -
+    - func, complex numbers, unsafe pointers
+    - unexported and not embedded
+    - unexported and embedded and not struct kind
+    - unexported and embedded pointers (from go1.10)
+
+Every other field in a struct will be encoded/decoded.
+
+Embedded fields are encoded as if they exist in the top-level struct,
+with some caveats. See Encode documentation.
+
+*/
+package codec
+
+// TODO:
+//   - For Go 1.11, when mid-stack inlining is enabled,
+//     we should use committed functions for writeXXX and readXXX calls.
+//     This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
+//     and using those (decReaderSwitch and encWriterSwitch) in all handles
+//     instead of encWriter and decReader.
+//     The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
+//     will be inlined, giving a performance bump for that typical case.
+//     However, it will only  be inlined if mid-stack inlining is enabled,
+//     as we call panic to raise errors, and panic currently prevents inlining.
+//
+// PUNTED:
+//   - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
+//     and use overlay methods on *BasicHandle to call through to extHandle after initializing
+//     the "xh *extHandle" to point to a real slice.
+//
+// BEFORE EACH RELEASE:
+//   - Look through and fix padding for each type, to eliminate false sharing
+//     - critical shared objects that are read many times
+//       TypeInfos
+//     - pooled objects:
+//       decNaked, decNakedContainers, codecFner, typeInfoLoadArray, 
+//     - small objects allocated independently, that we read/use much across threads:
+//       codecFn, typeInfo
+//     - Objects allocated independently and used a lot
+//       Decoder, Encoder,
+//       xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
+//     - In all above, arrange values modified together to be close to each other.
+//
+//     For all of these, either ensure that they occupy full cache lines,
+//     or ensure that the things just past the cache line boundary are hardly read/written
+//     e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
+//
+//     Occupying full cache lines means they occupy 8*N words (where N is an integer).
+//     Check this out by running: ./run.sh -z
+//     - look at those tagged ****, meaning they are not occupying full cache lines
+//     - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
+//   - Run "golint -min_confidence 0.81"
diff --git a/vendor/github.com/ugorji/go/codec/README.md b/vendor/github.com/ugorji/go/codec/README.md
new file mode 100644
index 0000000..50d65e5
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/README.md
@@ -0,0 +1,206 @@
+# Codec
+
+High Performance, Feature-Rich Idiomatic Go codec/encoding library for
+binc, msgpack, cbor, json.
+
+Supported Serialization formats are:
+
+  - msgpack: https://github.com/msgpack/msgpack
+  - binc:    http://github.com/ugorji/binc
+  - cbor:    http://cbor.io http://tools.ietf.org/html/rfc7049
+  - json:    http://json.org http://tools.ietf.org/html/rfc7159
+  - simple: 
+
+To install:
+
+    go get github.com/ugorji/go/codec
+
+This package will carefully use 'unsafe' for performance reasons in specific places.
+You can build without unsafe use by passing the safe or appengine tag
+i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
+go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
+go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
+
+Online documentation: http://godoc.org/github.com/ugorji/go/codec  
+Detailed Usage/How-to Primer: http://ugorji.net/blog/go-codec-primer
+
+The idiomatic Go support is as seen in other encoding packages in
+the standard library (ie json, xml, gob, etc).
+
+Rich Feature Set includes:
+
+  - Simple but extremely powerful and feature-rich API
+  - Support for go1.4 and above, while selectively using newer APIs for later releases
+  - Excellent code coverage ( > 90% )
+  - Very High Performance.
+    Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
+  - Careful selected use of 'unsafe' for targeted performance gains.
+    100% mode exists where 'unsafe' is not used at all.
+  - Lock-free (sans mutex) concurrency for scaling to 100's of cores
+  - Coerce types where appropriate
+    e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
+  - Corner Cases: 
+    Overflows, nil maps/slices, nil values in streams are handled correctly
+  - Standard field renaming via tags
+  - Support for omitting empty fields during an encoding
+  - Encoding from any value and decoding into pointer to any value
+    (struct, slice, map, primitives, pointers, interface{}, etc)
+  - Extensions to support efficient encoding/decoding of any named types
+  - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
+  - Support IsZero() bool to determine if a value is a zero value.
+    Analogous to time.Time.IsZero() bool.
+  - Decoding without a schema (into a interface{}).
+    Includes Options to configure what specific map or slice type to use
+    when decoding an encoded list or map into a nil interface{}
+  - Mapping a non-interface type to an interface, so we can decode appropriately
+    into any interface type with a correctly configured non-interface value.
+  - Encode a struct as an array, and decode struct from an array in the data stream
+  - Option to encode struct keys as numbers (instead of strings)
+    (to support structured streams with fields encoded as numeric codes)
+  - Comprehensive support for anonymous fields
+  - Fast (no-reflection) encoding/decoding of common maps and slices
+  - Code-generation for faster performance.
+  - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
+  - Support indefinite-length formats to enable true streaming 
+    (for formats which support it e.g. json, cbor)
+  - Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
+    This mostly applies to maps, where iteration order is non-deterministic.
+  - NIL in data stream decoded as zero value
+  - Never silently skip data when decoding.
+    User decides whether to return an error or silently skip data when keys or indexes
+    in the data stream do not map to fields in the struct.
+  - Encode/Decode from/to chan types (for iterative streaming support)
+  - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
+  - Provides a RPC Server and Client Codec for net/rpc communication protocol.
+  - Handle unique idiosyncrasies of codecs e.g. 
+    - For messagepack, configure how ambiguities in handling raw bytes are resolved 
+    - For messagepack, provide rpc server/client codec to support
+      msgpack-rpc protocol defined at:
+      https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
+
+## Extension Support
+
+Users can register a function to handle the encoding or decoding of
+their custom types.
+
+There are no restrictions on what the custom type can be. Some examples:
+
+    type BisSet   []int
+    type BitSet64 uint64
+    type UUID     string
+    type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
+    type GifImage struct { ... }
+
+As an illustration, MyStructWithUnexportedFields would normally be
+encoded as an empty map because it has no exported fields, while UUID
+would be encoded as a string. However, with extension support, you can
+encode any of these however you like.
+
+## Custom Encoding and Decoding
+
+This package maintains symmetry in the encoding and decoding halfs.
+We determine how to encode or decode by walking this decision tree
+
+  - is type a codec.Selfer?
+  - is there an extension registered for the type?
+  - is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
+  - is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
+  - is format text-based, and type an encoding.TextMarshaler?
+  - else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
+
+This symmetry is important to reduce chances of issues happening because the
+encoding and decoding sides are out of sync e.g. decoded via very specific
+encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
+
+Consequently, if a type only defines one-half of the symmetry
+(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
+then that type doesn't satisfy the check and we will continue walking down the
+decision tree.
+
+## RPC
+
+RPC Client and Server Codecs are implemented, so the codecs can be used
+with the standard net/rpc package.
+
+## Usage
+
+Typical usage model:
+
+    // create and configure Handle
+    var (
+      bh codec.BincHandle
+      mh codec.MsgpackHandle
+      ch codec.CborHandle
+    )
+
+    mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
+
+    // configure extensions
+    // e.g. for msgpack, define functions and enable Time support for tag 1
+    // mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
+
+    // create and use decoder/encoder
+    var (
+      r io.Reader
+      w io.Writer
+      b []byte
+      h = &bh // or mh to use msgpack
+    )
+
+    dec = codec.NewDecoder(r, h)
+    dec = codec.NewDecoderBytes(b, h)
+    err = dec.Decode(&v)
+
+    enc = codec.NewEncoder(w, h)
+    enc = codec.NewEncoderBytes(&b, h)
+    err = enc.Encode(v)
+
+    //RPC Server
+    go func() {
+        for {
+            conn, err := listener.Accept()
+            rpcCodec := codec.GoRpc.ServerCodec(conn, h)
+            //OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
+            rpc.ServeCodec(rpcCodec)
+        }
+    }()
+
+    //RPC Communication (client side)
+    conn, err = net.Dial("tcp", "localhost:5555")
+    rpcCodec := codec.GoRpc.ClientCodec(conn, h)
+    //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
+    client := rpc.NewClientWithCodec(rpcCodec)
+
+## Running Tests
+
+To run tests, use the following:
+
+    go test
+
+To run the full suite of tests, use the following:
+
+    go test -tags alltests -run Suite
+
+You can run the tag 'safe' to run tests or build in safe mode. e.g.
+
+    go test -tags safe -run Json
+    go test -tags "alltests safe" -run Suite
+
+## Running Benchmarks
+
+Please see http://github.com/ugorji/go-codec-bench .
+
+## Caveats
+
+Struct fields matching the following are ignored during encoding and decoding
+
+  - struct tag value set to -
+  - func, complex numbers, unsafe pointers
+  - unexported and not embedded
+  - unexported and embedded and not struct kind
+  - unexported and embedded pointers (from go1.10)
+
+Every other field in a struct will be encoded/decoded.
+
+Embedded fields are encoded as if they exist in the top-level struct,
+with some caveats. See Encode documentation.
diff --git a/vendor/github.com/ugorji/go/codec/binc.go b/vendor/github.com/ugorji/go/codec/binc.go
new file mode 100644
index 0000000..a3c96fe
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/binc.go
@@ -0,0 +1,1168 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"math"
+	"reflect"
+	"time"
+)
+
+const bincDoPrune = true // No longer needed. Needed before as C lib did not support pruning.
+
+// vd as low 4 bits (there are 16 slots)
+const (
+	bincVdSpecial byte = iota
+	bincVdPosInt
+	bincVdNegInt
+	bincVdFloat
+
+	bincVdString
+	bincVdByteArray
+	bincVdArray
+	bincVdMap
+
+	bincVdTimestamp
+	bincVdSmallInt
+	bincVdUnicodeOther
+	bincVdSymbol
+
+	bincVdDecimal
+	_               // open slot
+	_               // open slot
+	bincVdCustomExt = 0x0f
+)
+
+const (
+	bincSpNil byte = iota
+	bincSpFalse
+	bincSpTrue
+	bincSpNan
+	bincSpPosInf
+	bincSpNegInf
+	bincSpZeroFloat
+	bincSpZero
+	bincSpNegOne
+)
+
+const (
+	bincFlBin16 byte = iota
+	bincFlBin32
+	_ // bincFlBin32e
+	bincFlBin64
+	_ // bincFlBin64e
+	// others not currently supported
+)
+
+func bincdesc(vd, vs byte) string {
+	switch vd {
+	case bincVdSpecial:
+		switch vs {
+		case bincSpNil:
+			return "nil"
+		case bincSpFalse:
+			return "false"
+		case bincSpTrue:
+			return "true"
+		case bincSpNan, bincSpPosInf, bincSpNegInf, bincSpZeroFloat:
+			return "float"
+		case bincSpZero:
+			return "uint"
+		case bincSpNegOne:
+			return "int"
+		default:
+			return "unknown"
+		}
+	case bincVdSmallInt, bincVdPosInt:
+		return "uint"
+	case bincVdNegInt:
+		return "int"
+	case bincVdFloat:
+		return "float"
+	case bincVdSymbol:
+		return "string"
+	case bincVdString:
+		return "string"
+	case bincVdByteArray:
+		return "bytes"
+	case bincVdTimestamp:
+		return "time"
+	case bincVdCustomExt:
+		return "ext"
+	case bincVdArray:
+		return "array"
+	case bincVdMap:
+		return "map"
+	default:
+		return "unknown"
+	}
+}
+
+type bincEncDriver struct {
+	e *Encoder
+	h *BincHandle
+	w encWriter
+	m map[string]uint16 // symbols
+	b [16]byte          // scratch, used for encoding numbers - bigendian style
+	s uint16            // symbols sequencer
+	// c containerState
+	encDriverTrackContainerWriter
+	noBuiltInTypes
+	// encNoSeparator
+}
+
+func (e *bincEncDriver) EncodeNil() {
+	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
+}
+
+func (e *bincEncDriver) EncodeTime(t time.Time) {
+	if t.IsZero() {
+		e.EncodeNil()
+	} else {
+		bs := bincEncodeTime(t)
+		e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
+		e.w.writeb(bs)
+	}
+}
+
+func (e *bincEncDriver) EncodeBool(b bool) {
+	if b {
+		e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
+	} else {
+		e.w.writen1(bincVdSpecial<<4 | bincSpFalse)
+	}
+}
+
+func (e *bincEncDriver) EncodeFloat32(f float32) {
+	if f == 0 {
+		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
+		return
+	}
+	e.w.writen1(bincVdFloat<<4 | bincFlBin32)
+	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
+}
+
+func (e *bincEncDriver) EncodeFloat64(f float64) {
+	if f == 0 {
+		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
+		return
+	}
+	bigen.PutUint64(e.b[:8], math.Float64bits(f))
+	if bincDoPrune {
+		i := 7
+		for ; i >= 0 && (e.b[i] == 0); i-- {
+		}
+		i++
+		if i <= 6 {
+			e.w.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
+			e.w.writen1(byte(i))
+			e.w.writeb(e.b[:i])
+			return
+		}
+	}
+	e.w.writen1(bincVdFloat<<4 | bincFlBin64)
+	e.w.writeb(e.b[:8])
+}
+
+func (e *bincEncDriver) encIntegerPrune(bd byte, pos bool, v uint64, lim uint8) {
+	if lim == 4 {
+		bigen.PutUint32(e.b[:lim], uint32(v))
+	} else {
+		bigen.PutUint64(e.b[:lim], v)
+	}
+	if bincDoPrune {
+		i := pruneSignExt(e.b[:lim], pos)
+		e.w.writen1(bd | lim - 1 - byte(i))
+		e.w.writeb(e.b[i:lim])
+	} else {
+		e.w.writen1(bd | lim - 1)
+		e.w.writeb(e.b[:lim])
+	}
+}
+
+func (e *bincEncDriver) EncodeInt(v int64) {
+	const nbd byte = bincVdNegInt << 4
+	if v >= 0 {
+		e.encUint(bincVdPosInt<<4, true, uint64(v))
+	} else if v == -1 {
+		e.w.writen1(bincVdSpecial<<4 | bincSpNegOne)
+	} else {
+		e.encUint(bincVdNegInt<<4, false, uint64(-v))
+	}
+}
+
+func (e *bincEncDriver) EncodeUint(v uint64) {
+	e.encUint(bincVdPosInt<<4, true, v)
+}
+
+func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) {
+	if v == 0 {
+		e.w.writen1(bincVdSpecial<<4 | bincSpZero)
+	} else if pos && v >= 1 && v <= 16 {
+		e.w.writen1(bincVdSmallInt<<4 | byte(v-1))
+	} else if v <= math.MaxUint8 {
+		e.w.writen2(bd|0x0, byte(v))
+	} else if v <= math.MaxUint16 {
+		e.w.writen1(bd | 0x01)
+		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
+	} else if v <= math.MaxUint32 {
+		e.encIntegerPrune(bd, pos, v, 4)
+	} else {
+		e.encIntegerPrune(bd, pos, v, 8)
+	}
+}
+
+func (e *bincEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
+	bs := ext.WriteExt(rv)
+	if bs == nil {
+		e.EncodeNil()
+		return
+	}
+	e.encodeExtPreamble(uint8(xtag), len(bs))
+	e.w.writeb(bs)
+}
+
+func (e *bincEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
+	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
+	e.w.writeb(re.Data)
+}
+
+func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
+	e.encLen(bincVdCustomExt<<4, uint64(length))
+	e.w.writen1(xtag)
+}
+
+func (e *bincEncDriver) WriteArrayStart(length int) {
+	e.encLen(bincVdArray<<4, uint64(length))
+	e.c = containerArrayStart
+}
+
+func (e *bincEncDriver) WriteMapStart(length int) {
+	e.encLen(bincVdMap<<4, uint64(length))
+	e.c = containerMapStart
+}
+
+func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
+	if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
+		e.EncodeSymbol(v)
+		return
+	}
+	l := uint64(len(v))
+	e.encBytesLen(c, l)
+	if l > 0 {
+		e.w.writestr(v)
+	}
+}
+
+func (e *bincEncDriver) EncodeSymbol(v string) {
+	// if WriteSymbolsNoRefs {
+	// 	e.encodeString(cUTF8, v)
+	// 	return
+	// }
+
+	//symbols only offer benefit when string length > 1.
+	//This is because strings with length 1 take only 2 bytes to store
+	//(bd with embedded length, and single byte for string val).
+
+	l := len(v)
+	if l == 0 {
+		e.encBytesLen(cUTF8, 0)
+		return
+	} else if l == 1 {
+		e.encBytesLen(cUTF8, 1)
+		e.w.writen1(v[0])
+		return
+	}
+	if e.m == nil {
+		e.m = make(map[string]uint16, 16)
+	}
+	ui, ok := e.m[v]
+	if ok {
+		if ui <= math.MaxUint8 {
+			e.w.writen2(bincVdSymbol<<4, byte(ui))
+		} else {
+			e.w.writen1(bincVdSymbol<<4 | 0x8)
+			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
+		}
+	} else {
+		e.s++
+		ui = e.s
+		//ui = uint16(atomic.AddUint32(&e.s, 1))
+		e.m[v] = ui
+		var lenprec uint8
+		if l <= math.MaxUint8 {
+			// lenprec = 0
+		} else if l <= math.MaxUint16 {
+			lenprec = 1
+		} else if int64(l) <= math.MaxUint32 {
+			lenprec = 2
+		} else {
+			lenprec = 3
+		}
+		if ui <= math.MaxUint8 {
+			e.w.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
+		} else {
+			e.w.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
+			bigenHelper{e.b[:2], e.w}.writeUint16(ui)
+		}
+		if lenprec == 0 {
+			e.w.writen1(byte(l))
+		} else if lenprec == 1 {
+			bigenHelper{e.b[:2], e.w}.writeUint16(uint16(l))
+		} else if lenprec == 2 {
+			bigenHelper{e.b[:4], e.w}.writeUint32(uint32(l))
+		} else {
+			bigenHelper{e.b[:8], e.w}.writeUint64(uint64(l))
+		}
+		e.w.writestr(v)
+	}
+}
+
+func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	if v == nil {
+		e.EncodeNil()
+		return
+	}
+	l := uint64(len(v))
+	e.encBytesLen(c, l)
+	if l > 0 {
+		e.w.writeb(v)
+	}
+}
+
+func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
+	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
+	if c == cRAW {
+		e.encLen(bincVdByteArray<<4, length)
+	} else {
+		e.encLen(bincVdString<<4, length)
+	}
+}
+
+func (e *bincEncDriver) encLen(bd byte, l uint64) {
+	if l < 12 {
+		e.w.writen1(bd | uint8(l+4))
+	} else {
+		e.encLenNumber(bd, l)
+	}
+}
+
+func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
+	if v <= math.MaxUint8 {
+		e.w.writen2(bd, byte(v))
+	} else if v <= math.MaxUint16 {
+		e.w.writen1(bd | 0x01)
+		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
+	} else if v <= math.MaxUint32 {
+		e.w.writen1(bd | 0x02)
+		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
+	} else {
+		e.w.writen1(bd | 0x03)
+		bigenHelper{e.b[:8], e.w}.writeUint64(uint64(v))
+	}
+}
+
+//------------------------------------
+
+type bincDecSymbol struct {
+	s string
+	b []byte
+	i uint16
+}
+
+type bincDecDriver struct {
+	decDriverNoopContainerReader
+	noBuiltInTypes
+
+	d      *Decoder
+	h      *BincHandle
+	r      decReader
+	br     bool // bytes reader
+	bdRead bool
+	bd     byte
+	vd     byte
+	vs     byte
+	_      [3]byte // padding
+	// linear searching on this slice is ok,
+	// because we typically expect < 32 symbols in each stream.
+	s []bincDecSymbol
+
+	// noStreamingCodec
+	// decNoSeparator
+
+	b [8 * 8]byte // scratch
+}
+
+func (d *bincDecDriver) readNextBd() {
+	d.bd = d.r.readn1()
+	d.vd = d.bd >> 4
+	d.vs = d.bd & 0x0f
+	d.bdRead = true
+}
+
+func (d *bincDecDriver) uncacheRead() {
+	if d.bdRead {
+		d.r.unreadn1()
+		d.bdRead = false
+	}
+}
+
+func (d *bincDecDriver) ContainerType() (vt valueType) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.vd == bincVdSpecial && d.vs == bincSpNil {
+		return valueTypeNil
+	} else if d.vd == bincVdByteArray {
+		return valueTypeBytes
+	} else if d.vd == bincVdString {
+		return valueTypeString
+	} else if d.vd == bincVdArray {
+		return valueTypeArray
+	} else if d.vd == bincVdMap {
+		return valueTypeMap
+	}
+	// else {
+	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
+	// }
+	return valueTypeUnset
+}
+
+func (d *bincDecDriver) TryDecodeAsNil() bool {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == bincVdSpecial<<4|bincSpNil {
+		d.bdRead = false
+		return true
+	}
+	return false
+}
+
+func (d *bincDecDriver) DecodeTime() (t time.Time) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == bincVdSpecial<<4|bincSpNil {
+		d.bdRead = false
+		return
+	}
+	if d.vd != bincVdTimestamp {
+		d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	t, err := bincDecodeTime(d.r.readx(int(d.vs)))
+	if err != nil {
+		panic(err)
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
+	if vs&0x8 == 0 {
+		d.r.readb(d.b[0:defaultLen])
+	} else {
+		l := d.r.readn1()
+		if l > 8 {
+			d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", l)
+			return
+		}
+		for i := l; i < 8; i++ {
+			d.b[i] = 0
+		}
+		d.r.readb(d.b[0:l])
+	}
+}
+
+func (d *bincDecDriver) decFloat() (f float64) {
+	//if true { f = math.Float64frombits(bigen.Uint64(d.r.readx(8))); break; }
+	if x := d.vs & 0x7; x == bincFlBin32 {
+		d.decFloatPre(d.vs, 4)
+		f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
+	} else if x == bincFlBin64 {
+		d.decFloatPre(d.vs, 8)
+		f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
+	} else {
+		d.d.errorf("read float - only float32 and float64 are supported - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	return
+}
+
+func (d *bincDecDriver) decUint() (v uint64) {
+	// need to inline the code (interface conversion and type assertion expensive)
+	switch d.vs {
+	case 0:
+		v = uint64(d.r.readn1())
+	case 1:
+		d.r.readb(d.b[6:8])
+		v = uint64(bigen.Uint16(d.b[6:8]))
+	case 2:
+		d.b[4] = 0
+		d.r.readb(d.b[5:8])
+		v = uint64(bigen.Uint32(d.b[4:8]))
+	case 3:
+		d.r.readb(d.b[4:8])
+		v = uint64(bigen.Uint32(d.b[4:8]))
+	case 4, 5, 6:
+		lim := int(7 - d.vs)
+		d.r.readb(d.b[lim:8])
+		for i := 0; i < lim; i++ {
+			d.b[i] = 0
+		}
+		v = uint64(bigen.Uint64(d.b[:8]))
+	case 7:
+		d.r.readb(d.b[:8])
+		v = uint64(bigen.Uint64(d.b[:8]))
+	default:
+		d.d.errorf("unsigned integers with greater than 64 bits of precision not supported")
+		return
+	}
+	return
+}
+
+func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	vd, vs := d.vd, d.vs
+	if vd == bincVdPosInt {
+		ui = d.decUint()
+	} else if vd == bincVdNegInt {
+		ui = d.decUint()
+		neg = true
+	} else if vd == bincVdSmallInt {
+		ui = uint64(d.vs) + 1
+	} else if vd == bincVdSpecial {
+		if vs == bincSpZero {
+			//i = 0
+		} else if vs == bincSpNegOne {
+			neg = true
+			ui = 1
+		} else {
+			d.d.errorf("integer decode fails - invalid special value from descriptor %x-%x/%s",
+				d.vd, d.vs, bincdesc(d.vd, d.vs))
+			return
+		}
+	} else {
+		d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
+		return
+	}
+	return
+}
+
+func (d *bincDecDriver) DecodeInt64() (i int64) {
+	ui, neg := d.decCheckInteger()
+	i = chkOvf.SignedIntV(ui)
+	if neg {
+		i = -i
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) DecodeUint64() (ui uint64) {
+	ui, neg := d.decCheckInteger()
+	if neg {
+		d.d.errorf("assigning negative signed value to unsigned integer type")
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) DecodeFloat64() (f float64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	vd, vs := d.vd, d.vs
+	if vd == bincVdSpecial {
+		d.bdRead = false
+		if vs == bincSpNan {
+			return math.NaN()
+		} else if vs == bincSpPosInf {
+			return math.Inf(1)
+		} else if vs == bincSpZeroFloat || vs == bincSpZero {
+			return
+		} else if vs == bincSpNegInf {
+			return math.Inf(-1)
+		} else {
+			d.d.errorf("float - invalid special value from descriptor %x-%x/%s",
+				d.vd, d.vs, bincdesc(d.vd, d.vs))
+			return
+		}
+	} else if vd == bincVdFloat {
+		f = d.decFloat()
+	} else {
+		f = float64(d.DecodeInt64())
+	}
+	d.bdRead = false
+	return
+}
+
+// bool can be decoded from bool only (single byte).
+func (d *bincDecDriver) DecodeBool() (b bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if bd := d.bd; bd == (bincVdSpecial | bincSpFalse) {
+		// b = false
+	} else if bd == (bincVdSpecial | bincSpTrue) {
+		b = true
+	} else {
+		d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) ReadMapStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.vd != bincVdMap {
+		d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	length = d.decLen()
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) ReadArrayStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.vd != bincVdArray {
+		d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	length = d.decLen()
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) decLen() int {
+	if d.vs > 3 {
+		return int(d.vs - 4)
+	}
+	return int(d.decLenNumber())
+}
+
+func (d *bincDecDriver) decLenNumber() (v uint64) {
+	if x := d.vs; x == 0 {
+		v = uint64(d.r.readn1())
+	} else if x == 1 {
+		d.r.readb(d.b[6:8])
+		v = uint64(bigen.Uint16(d.b[6:8]))
+	} else if x == 2 {
+		d.r.readb(d.b[4:8])
+		v = uint64(bigen.Uint32(d.b[4:8]))
+	} else {
+		d.r.readb(d.b[:8])
+		v = bigen.Uint64(d.b[:8])
+	}
+	return
+}
+
+func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
+	bs2 []byte, s string) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == bincVdSpecial<<4|bincSpNil {
+		d.bdRead = false
+		return
+	}
+	var slen = -1
+	// var ok bool
+	switch d.vd {
+	case bincVdString, bincVdByteArray:
+		slen = d.decLen()
+		if zerocopy {
+			if d.br {
+				bs2 = d.r.readx(slen)
+			} else if len(bs) == 0 {
+				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, d.b[:])
+			} else {
+				bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
+			}
+		} else {
+			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, bs)
+		}
+		if withString {
+			s = string(bs2)
+		}
+	case bincVdSymbol:
+		// zerocopy doesn't apply for symbols,
+		// as the values must be stored in a table for later use.
+		//
+		//from vs: extract numSymbolBytes, containsStringVal, strLenPrecision,
+		//extract symbol
+		//if containsStringVal, read it and put in map
+		//else look in map for string value
+		var symbol uint16
+		vs := d.vs
+		if vs&0x8 == 0 {
+			symbol = uint16(d.r.readn1())
+		} else {
+			symbol = uint16(bigen.Uint16(d.r.readx(2)))
+		}
+		if d.s == nil {
+			d.s = make([]bincDecSymbol, 0, 16)
+		}
+
+		if vs&0x4 == 0 {
+			for i := range d.s {
+				j := &d.s[i]
+				if j.i == symbol {
+					bs2 = j.b
+					if withString {
+						if j.s == "" && bs2 != nil {
+							j.s = string(bs2)
+						}
+						s = j.s
+					}
+					break
+				}
+			}
+		} else {
+			switch vs & 0x3 {
+			case 0:
+				slen = int(d.r.readn1())
+			case 1:
+				slen = int(bigen.Uint16(d.r.readx(2)))
+			case 2:
+				slen = int(bigen.Uint32(d.r.readx(4)))
+			case 3:
+				slen = int(bigen.Uint64(d.r.readx(8)))
+			}
+			// since using symbols, do not store any part of
+			// the parameter bs in the map, as it might be a shared buffer.
+			// bs2 = decByteSlice(d.r, slen, bs)
+			bs2 = decByteSlice(d.r, slen, d.d.h.MaxInitLen, nil)
+			if withString {
+				s = string(bs2)
+			}
+			d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2})
+		}
+	default:
+		d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) DecodeString() (s string) {
+	// DecodeBytes does not accommodate symbols, whose impl stores string version in map.
+	// Use decStringAndBytes directly.
+	// return string(d.DecodeBytes(d.b[:], true, true))
+	_, s = d.decStringAndBytes(d.b[:], true, true)
+	return
+}
+
+func (d *bincDecDriver) DecodeStringAsBytes() (s []byte) {
+	s, _ = d.decStringAndBytes(d.b[:], false, true)
+	return
+}
+
+func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == bincVdSpecial<<4|bincSpNil {
+		d.bdRead = false
+		return nil
+	}
+	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
+	if d.vd == bincVdArray {
+		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
+		return
+	}
+	var clen int
+	if d.vd == bincVdString || d.vd == bincVdByteArray {
+		clen = d.decLen()
+	} else {
+		d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	d.bdRead = false
+	if zerocopy {
+		if d.br {
+			return d.r.readx(clen)
+		} else if len(bs) == 0 {
+			bs = d.b[:]
+		}
+	}
+	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
+}
+
+func (d *bincDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
+	if xtag > 0xff {
+		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		return
+	}
+	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
+	realxtag = uint64(realxtag1)
+	if ext == nil {
+		re := rv.(*RawExt)
+		re.Tag = realxtag
+		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
+	} else {
+		ext.ReadExt(rv, xbs)
+	}
+	return
+}
+
+func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.vd == bincVdCustomExt {
+		l := d.decLen()
+		xtag = d.r.readn1()
+		if verifyTag && xtag != tag {
+			d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag)
+			return
+		}
+		xbs = d.r.readx(l)
+	} else if d.vd == bincVdByteArray {
+		xbs = d.DecodeBytes(nil, true)
+	} else {
+		d.d.errorf("ext - expecting extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *bincDecDriver) DecodeNaked() {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+
+	n := d.d.n
+	var decodeFurther bool
+
+	switch d.vd {
+	case bincVdSpecial:
+		switch d.vs {
+		case bincSpNil:
+			n.v = valueTypeNil
+		case bincSpFalse:
+			n.v = valueTypeBool
+			n.b = false
+		case bincSpTrue:
+			n.v = valueTypeBool
+			n.b = true
+		case bincSpNan:
+			n.v = valueTypeFloat
+			n.f = math.NaN()
+		case bincSpPosInf:
+			n.v = valueTypeFloat
+			n.f = math.Inf(1)
+		case bincSpNegInf:
+			n.v = valueTypeFloat
+			n.f = math.Inf(-1)
+		case bincSpZeroFloat:
+			n.v = valueTypeFloat
+			n.f = float64(0)
+		case bincSpZero:
+			n.v = valueTypeUint
+			n.u = uint64(0) // int8(0)
+		case bincSpNegOne:
+			n.v = valueTypeInt
+			n.i = int64(-1) // int8(-1)
+		default:
+			d.d.errorf("cannot infer value - unrecognized special value from descriptor %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs))
+		}
+	case bincVdSmallInt:
+		n.v = valueTypeUint
+		n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1
+	case bincVdPosInt:
+		n.v = valueTypeUint
+		n.u = d.decUint()
+	case bincVdNegInt:
+		n.v = valueTypeInt
+		n.i = -(int64(d.decUint()))
+	case bincVdFloat:
+		n.v = valueTypeFloat
+		n.f = d.decFloat()
+	case bincVdSymbol:
+		n.v = valueTypeSymbol
+		n.s = d.DecodeString()
+	case bincVdString:
+		n.v = valueTypeString
+		n.s = d.DecodeString()
+	case bincVdByteArray:
+		n.v = valueTypeBytes
+		n.l = d.DecodeBytes(nil, false)
+	case bincVdTimestamp:
+		n.v = valueTypeTime
+		tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
+		if err != nil {
+			panic(err)
+		}
+		n.t = tt
+	case bincVdCustomExt:
+		n.v = valueTypeExt
+		l := d.decLen()
+		n.u = uint64(d.r.readn1())
+		n.l = d.r.readx(l)
+	case bincVdArray:
+		n.v = valueTypeArray
+		decodeFurther = true
+	case bincVdMap:
+		n.v = valueTypeMap
+		decodeFurther = true
+	default:
+		d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs))
+	}
+
+	if !decodeFurther {
+		d.bdRead = false
+	}
+	if n.v == valueTypeUint && d.h.SignedInteger {
+		n.v = valueTypeInt
+		n.i = int64(n.u)
+	}
+	return
+}
+
+//------------------------------------
+
+//BincHandle is a Handle for the Binc Schema-Free Encoding Format
+//defined at https://github.com/ugorji/binc .
+//
+//BincHandle currently supports all Binc features with the following EXCEPTIONS:
+//  - only integers up to 64 bits of precision are supported.
+//    big integers are unsupported.
+//  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
+//    extended precision and decimal IEEE 754 floats are unsupported.
+//  - Only UTF-8 strings supported.
+//    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
+//
+//Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
+type BincHandle struct {
+	BasicHandle
+	binaryEncodingType
+	noElemSeparators
+
+	// AsSymbols defines what should be encoded as symbols.
+	//
+	// Encoding as symbols can reduce the encoded size significantly.
+	//
+	// However, during decoding, each string to be encoded as a symbol must
+	// be checked to see if it has been seen before. Consequently, encoding time
+	// will increase if using symbols, because string comparisons has a clear cost.
+	//
+	// Values:
+	// - 0: default: library uses best judgement
+	// - 1: use symbols
+	// - 2: do not use symbols
+	AsSymbols uint8
+
+	// AsSymbols: may later on introduce more options ...
+	// - m: map keys
+	// - s: struct fields
+	// - n: none
+	// - a: all: same as m, s, ...
+
+	// _ [1]uint64 // padding
+}
+
+// Name returns the name of the handle: binc
+func (h *BincHandle) Name() string { return "binc" }
+
+// SetBytesExt sets an extension
+func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+}
+
+func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
+	return &bincEncDriver{e: e, h: h, w: e.w}
+}
+
+func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
+	return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+}
+
+func (e *bincEncDriver) reset() {
+	e.w = e.e.w
+	e.s = 0
+	e.c = 0
+	e.m = nil
+}
+
+func (d *bincDecDriver) reset() {
+	d.r, d.br = d.d.r, d.d.bytes
+	d.s = nil
+	d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
+}
+
+// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
+
+// EncodeTime encodes a time.Time as a []byte, including
+// information on the instant in time and UTC offset.
+//
+// Format Description
+//
+//   A timestamp is composed of 3 components:
+//
+//   - secs: signed integer representing seconds since unix epoch
+//   - nsces: unsigned integer representing fractional seconds as a
+//     nanosecond offset within secs, in the range 0 <= nsecs < 1e9
+//   - tz: signed integer representing timezone offset in minutes east of UTC,
+//     and a dst (daylight savings time) flag
+//
+//   When encoding a timestamp, the first byte is the descriptor, which
+//   defines which components are encoded and how many bytes are used to
+//   encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
+//   is not encoded in the byte array explicitly*.
+//
+//       Descriptor 8 bits are of the form `A B C DDD EE`:
+//           A:   Is secs component encoded? 1 = true
+//           B:   Is nsecs component encoded? 1 = true
+//           C:   Is tz component encoded? 1 = true
+//           DDD: Number of extra bytes for secs (range 0-7).
+//                If A = 1, secs encoded in DDD+1 bytes.
+//                    If A = 0, secs is not encoded, and is assumed to be 0.
+//                    If A = 1, then we need at least 1 byte to encode secs.
+//                    DDD says the number of extra bytes beyond that 1.
+//                    E.g. if DDD=0, then secs is represented in 1 byte.
+//                         if DDD=2, then secs is represented in 3 bytes.
+//           EE:  Number of extra bytes for nsecs (range 0-3).
+//                If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
+//
+//   Following the descriptor bytes, subsequent bytes are:
+//
+//       secs component encoded in `DDD + 1` bytes (if A == 1)
+//       nsecs component encoded in `EE + 1` bytes (if B == 1)
+//       tz component encoded in 2 bytes (if C == 1)
+//
+//   secs and nsecs components are integers encoded in a BigEndian
+//   2-complement encoding format.
+//
+//   tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
+//   Least significant bit 0 are described below:
+//
+//       Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
+//       Bit 15 = have\_dst: set to 1 if we set the dst flag.
+//       Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
+//       Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
+//
+func bincEncodeTime(t time.Time) []byte {
+	//t := rv.Interface().(time.Time)
+	tsecs, tnsecs := t.Unix(), t.Nanosecond()
+	var (
+		bd   byte
+		btmp [8]byte
+		bs   [16]byte
+		i    int = 1
+	)
+	l := t.Location()
+	if l == time.UTC {
+		l = nil
+	}
+	if tsecs != 0 {
+		bd = bd | 0x80
+		bigen.PutUint64(btmp[:], uint64(tsecs))
+		f := pruneSignExt(btmp[:], tsecs >= 0)
+		bd = bd | (byte(7-f) << 2)
+		copy(bs[i:], btmp[f:])
+		i = i + (8 - f)
+	}
+	if tnsecs != 0 {
+		bd = bd | 0x40
+		bigen.PutUint32(btmp[:4], uint32(tnsecs))
+		f := pruneSignExt(btmp[:4], true)
+		bd = bd | byte(3-f)
+		copy(bs[i:], btmp[f:4])
+		i = i + (4 - f)
+	}
+	if l != nil {
+		bd = bd | 0x20
+		// Note that Go Libs do not give access to dst flag.
+		_, zoneOffset := t.Zone()
+		//zoneName, zoneOffset := t.Zone()
+		zoneOffset /= 60
+		z := uint16(zoneOffset)
+		bigen.PutUint16(btmp[:2], z)
+		// clear dst flags
+		bs[i] = btmp[0] & 0x3f
+		bs[i+1] = btmp[1]
+		i = i + 2
+	}
+	bs[0] = bd
+	return bs[0:i]
+}
+
+// bincDecodeTime decodes a []byte into a time.Time.
+func bincDecodeTime(bs []byte) (tt time.Time, err error) {
+	bd := bs[0]
+	var (
+		tsec  int64
+		tnsec uint32
+		tz    uint16
+		i     byte = 1
+		i2    byte
+		n     byte
+	)
+	if bd&(1<<7) != 0 {
+		var btmp [8]byte
+		n = ((bd >> 2) & 0x7) + 1
+		i2 = i + n
+		copy(btmp[8-n:], bs[i:i2])
+		//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
+		if bs[i]&(1<<7) != 0 {
+			copy(btmp[0:8-n], bsAll0xff)
+			//for j,k := byte(0), 8-n; j < k; j++ {	btmp[j] = 0xff }
+		}
+		i = i2
+		tsec = int64(bigen.Uint64(btmp[:]))
+	}
+	if bd&(1<<6) != 0 {
+		var btmp [4]byte
+		n = (bd & 0x3) + 1
+		i2 = i + n
+		copy(btmp[4-n:], bs[i:i2])
+		i = i2
+		tnsec = bigen.Uint32(btmp[:])
+	}
+	if bd&(1<<5) == 0 {
+		tt = time.Unix(tsec, int64(tnsec)).UTC()
+		return
+	}
+	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
+	// However, we need name here, so it can be shown when time is printed.
+	// Zone name is in form: UTC-08:00.
+	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
+
+	i2 = i + 2
+	tz = bigen.Uint16(bs[i:i2])
+	// i = i2
+	// sign extend sign bit into top 2 MSB (which were dst bits):
+	if tz&(1<<13) == 0 { // positive
+		tz = tz & 0x3fff //clear 2 MSBs: dst bits
+	} else { // negative
+		tz = tz | 0xc000 //set 2 MSBs: dst bits
+	}
+	tzint := int16(tz)
+	if tzint == 0 {
+		tt = time.Unix(tsec, int64(tnsec)).UTC()
+	} else {
+		// For Go Time, do not use a descriptive timezone.
+		// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
+		// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
+		// var zoneName = timeLocUTCName(tzint)
+		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
+	}
+	return
+}
+
+var _ decDriver = (*bincDecDriver)(nil)
+var _ encDriver = (*bincEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/cbor.go b/vendor/github.com/ugorji/go/codec/cbor.go
new file mode 100644
index 0000000..7633c04
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/cbor.go
@@ -0,0 +1,756 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"math"
+	"reflect"
+	"time"
+)
+
+const (
+	cborMajorUint byte = iota
+	cborMajorNegInt
+	cborMajorBytes
+	cborMajorText
+	cborMajorArray
+	cborMajorMap
+	cborMajorTag
+	cborMajorOther
+)
+
+const (
+	cborBdFalse byte = 0xf4 + iota
+	cborBdTrue
+	cborBdNil
+	cborBdUndefined
+	cborBdExt
+	cborBdFloat16
+	cborBdFloat32
+	cborBdFloat64
+)
+
+const (
+	cborBdIndefiniteBytes  byte = 0x5f
+	cborBdIndefiniteString      = 0x7f
+	cborBdIndefiniteArray       = 0x9f
+	cborBdIndefiniteMap         = 0xbf
+	cborBdBreak                 = 0xff
+)
+
+// These define some in-stream descriptors for
+// manual encoding e.g. when doing explicit indefinite-length
+const (
+	CborStreamBytes  byte = 0x5f
+	CborStreamString      = 0x7f
+	CborStreamArray       = 0x9f
+	CborStreamMap         = 0xbf
+	CborStreamBreak       = 0xff
+)
+
+const (
+	cborBaseUint   byte = 0x00
+	cborBaseNegInt      = 0x20
+	cborBaseBytes       = 0x40
+	cborBaseString      = 0x60
+	cborBaseArray       = 0x80
+	cborBaseMap         = 0xa0
+	cborBaseTag         = 0xc0
+	cborBaseSimple      = 0xe0
+)
+
+func cbordesc(bd byte) string {
+	switch bd {
+	case cborBdNil:
+		return "nil"
+	case cborBdFalse:
+		return "false"
+	case cborBdTrue:
+		return "true"
+	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
+		return "float"
+	case cborBdIndefiniteBytes:
+		return "bytes*"
+	case cborBdIndefiniteString:
+		return "string*"
+	case cborBdIndefiniteArray:
+		return "array*"
+	case cborBdIndefiniteMap:
+		return "map*"
+	default:
+		switch {
+		case bd >= cborBaseUint && bd < cborBaseNegInt:
+			return "(u)int"
+		case bd >= cborBaseNegInt && bd < cborBaseBytes:
+			return "int"
+		case bd >= cborBaseBytes && bd < cborBaseString:
+			return "bytes"
+		case bd >= cborBaseString && bd < cborBaseArray:
+			return "string"
+		case bd >= cborBaseArray && bd < cborBaseMap:
+			return "array"
+		case bd >= cborBaseMap && bd < cborBaseTag:
+			return "map"
+		case bd >= cborBaseTag && bd < cborBaseSimple:
+			return "ext"
+		default:
+			return "unknown"
+		}
+	}
+}
+
+// -------------------
+
+type cborEncDriver struct {
+	noBuiltInTypes
+	encDriverNoopContainerWriter
+	// encNoSeparator
+	e *Encoder
+	w encWriter
+	h *CborHandle
+	x [8]byte
+	_ [3]uint64 // padding
+}
+
+func (e *cborEncDriver) EncodeNil() {
+	e.w.writen1(cborBdNil)
+}
+
+func (e *cborEncDriver) EncodeBool(b bool) {
+	if b {
+		e.w.writen1(cborBdTrue)
+	} else {
+		e.w.writen1(cborBdFalse)
+	}
+}
+
+func (e *cborEncDriver) EncodeFloat32(f float32) {
+	e.w.writen1(cborBdFloat32)
+	bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
+}
+
+func (e *cborEncDriver) EncodeFloat64(f float64) {
+	e.w.writen1(cborBdFloat64)
+	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
+}
+
+func (e *cborEncDriver) encUint(v uint64, bd byte) {
+	if v <= 0x17 {
+		e.w.writen1(byte(v) + bd)
+	} else if v <= math.MaxUint8 {
+		e.w.writen2(bd+0x18, uint8(v))
+	} else if v <= math.MaxUint16 {
+		e.w.writen1(bd + 0x19)
+		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(v))
+	} else if v <= math.MaxUint32 {
+		e.w.writen1(bd + 0x1a)
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v))
+	} else { // if v <= math.MaxUint64 {
+		e.w.writen1(bd + 0x1b)
+		bigenHelper{e.x[:8], e.w}.writeUint64(v)
+	}
+}
+
+func (e *cborEncDriver) EncodeInt(v int64) {
+	if v < 0 {
+		e.encUint(uint64(-1-v), cborBaseNegInt)
+	} else {
+		e.encUint(uint64(v), cborBaseUint)
+	}
+}
+
+func (e *cborEncDriver) EncodeUint(v uint64) {
+	e.encUint(v, cborBaseUint)
+}
+
+func (e *cborEncDriver) encLen(bd byte, length int) {
+	e.encUint(uint64(length), bd)
+}
+
+func (e *cborEncDriver) EncodeTime(t time.Time) {
+	if t.IsZero() {
+		e.EncodeNil()
+	} else if e.h.TimeRFC3339 {
+		e.encUint(0, cborBaseTag)
+		e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
+	} else {
+		e.encUint(1, cborBaseTag)
+		t = t.UTC().Round(time.Microsecond)
+		sec, nsec := t.Unix(), uint64(t.Nanosecond())
+		if nsec == 0 {
+			e.EncodeInt(sec)
+		} else {
+			e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
+		}
+	}
+}
+
+func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
+	e.encUint(uint64(xtag), cborBaseTag)
+	if v := ext.ConvertExt(rv); v == nil {
+		e.EncodeNil()
+	} else {
+		en.encode(v)
+	}
+}
+
+func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
+	e.encUint(uint64(re.Tag), cborBaseTag)
+	if false && re.Data != nil {
+		en.encode(re.Data)
+	} else if re.Value != nil {
+		en.encode(re.Value)
+	} else {
+		e.EncodeNil()
+	}
+}
+
+func (e *cborEncDriver) WriteArrayStart(length int) {
+	if e.h.IndefiniteLength {
+		e.w.writen1(cborBdIndefiniteArray)
+	} else {
+		e.encLen(cborBaseArray, length)
+	}
+}
+
+func (e *cborEncDriver) WriteMapStart(length int) {
+	if e.h.IndefiniteLength {
+		e.w.writen1(cborBdIndefiniteMap)
+	} else {
+		e.encLen(cborBaseMap, length)
+	}
+}
+
+func (e *cborEncDriver) WriteMapEnd() {
+	if e.h.IndefiniteLength {
+		e.w.writen1(cborBdBreak)
+	}
+}
+
+func (e *cborEncDriver) WriteArrayEnd() {
+	if e.h.IndefiniteLength {
+		e.w.writen1(cborBdBreak)
+	}
+}
+
+func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
+	e.encStringBytesS(cborBaseString, v)
+}
+
+func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	if v == nil {
+		e.EncodeNil()
+	} else if c == cRAW {
+		e.encStringBytesS(cborBaseBytes, stringView(v))
+	} else {
+		e.encStringBytesS(cborBaseString, stringView(v))
+	}
+}
+
+func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
+	if e.h.IndefiniteLength {
+		if bb == cborBaseBytes {
+			e.w.writen1(cborBdIndefiniteBytes)
+		} else {
+			e.w.writen1(cborBdIndefiniteString)
+		}
+		blen := len(v) / 4
+		if blen == 0 {
+			blen = 64
+		} else if blen > 1024 {
+			blen = 1024
+		}
+		for i := 0; i < len(v); {
+			var v2 string
+			i2 := i + blen
+			if i2 < len(v) {
+				v2 = v[i:i2]
+			} else {
+				v2 = v[i:]
+			}
+			e.encLen(bb, len(v2))
+			e.w.writestr(v2)
+			i = i2
+		}
+		e.w.writen1(cborBdBreak)
+	} else {
+		e.encLen(bb, len(v))
+		e.w.writestr(v)
+	}
+}
+
+// ----------------------
+
+type cborDecDriver struct {
+	d *Decoder
+	h *CborHandle
+	r decReader
+	// b      [scratchByteArrayLen]byte
+	br     bool // bytes reader
+	bdRead bool
+	bd     byte
+	noBuiltInTypes
+	// decNoSeparator
+	decDriverNoopContainerReader
+	_ [3]uint64 // padding
+}
+
+func (d *cborDecDriver) readNextBd() {
+	d.bd = d.r.readn1()
+	d.bdRead = true
+}
+
+func (d *cborDecDriver) uncacheRead() {
+	if d.bdRead {
+		d.r.unreadn1()
+		d.bdRead = false
+	}
+}
+
+func (d *cborDecDriver) ContainerType() (vt valueType) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == cborBdNil {
+		return valueTypeNil
+	} else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
+		return valueTypeBytes
+	} else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) {
+		return valueTypeString
+	} else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
+		return valueTypeArray
+	} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
+		return valueTypeMap
+	}
+	// else {
+	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
+	// }
+	return valueTypeUnset
+}
+
+func (d *cborDecDriver) TryDecodeAsNil() bool {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	// treat Nil and Undefined as nil values
+	if d.bd == cborBdNil || d.bd == cborBdUndefined {
+		d.bdRead = false
+		return true
+	}
+	return false
+}
+
+func (d *cborDecDriver) CheckBreak() bool {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == cborBdBreak {
+		d.bdRead = false
+		return true
+	}
+	return false
+}
+
+func (d *cborDecDriver) decUint() (ui uint64) {
+	v := d.bd & 0x1f
+	if v <= 0x17 {
+		ui = uint64(v)
+	} else {
+		if v == 0x18 {
+			ui = uint64(d.r.readn1())
+		} else if v == 0x19 {
+			ui = uint64(bigen.Uint16(d.r.readx(2)))
+		} else if v == 0x1a {
+			ui = uint64(bigen.Uint32(d.r.readx(4)))
+		} else if v == 0x1b {
+			ui = uint64(bigen.Uint64(d.r.readx(8)))
+		} else {
+			d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
+			return
+		}
+	}
+	return
+}
+
+func (d *cborDecDriver) decCheckInteger() (neg bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	major := d.bd >> 5
+	if major == cborMajorUint {
+	} else if major == cborMajorNegInt {
+		neg = true
+	} else {
+		d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
+		return
+	}
+	return
+}
+
+func (d *cborDecDriver) DecodeInt64() (i int64) {
+	neg := d.decCheckInteger()
+	ui := d.decUint()
+	// check if this number can be converted to an int without overflow
+	if neg {
+		i = -(chkOvf.SignedIntV(ui + 1))
+	} else {
+		i = chkOvf.SignedIntV(ui)
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *cborDecDriver) DecodeUint64() (ui uint64) {
+	if d.decCheckInteger() {
+		d.d.errorf("assigning negative signed value to unsigned type")
+		return
+	}
+	ui = d.decUint()
+	d.bdRead = false
+	return
+}
+
+func (d *cborDecDriver) DecodeFloat64() (f float64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if bd := d.bd; bd == cborBdFloat16 {
+		f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.r.readx(2)))))
+	} else if bd == cborBdFloat32 {
+		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
+	} else if bd == cborBdFloat64 {
+		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
+	} else if bd >= cborBaseUint && bd < cborBaseBytes {
+		f = float64(d.DecodeInt64())
+	} else {
+		d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+// bool can be decoded from bool only (single byte).
+func (d *cborDecDriver) DecodeBool() (b bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if bd := d.bd; bd == cborBdTrue {
+		b = true
+	} else if bd == cborBdFalse {
+	} else {
+		d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *cborDecDriver) ReadMapStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	d.bdRead = false
+	if d.bd == cborBdIndefiniteMap {
+		return -1
+	}
+	return d.decLen()
+}
+
+func (d *cborDecDriver) ReadArrayStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	d.bdRead = false
+	if d.bd == cborBdIndefiniteArray {
+		return -1
+	}
+	return d.decLen()
+}
+
+func (d *cborDecDriver) decLen() int {
+	return int(d.decUint())
+}
+
+func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
+	d.bdRead = false
+	for {
+		if d.CheckBreak() {
+			break
+		}
+		if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
+			d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
+				" got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
+			return nil
+		}
+		n := d.decLen()
+		oldLen := len(bs)
+		newLen := oldLen + n
+		if newLen > cap(bs) {
+			bs2 := make([]byte, newLen, 2*cap(bs)+n)
+			copy(bs2, bs)
+			bs = bs2
+		} else {
+			bs = bs[:newLen]
+		}
+		d.r.readb(bs[oldLen:newLen])
+		// bs = append(bs, d.r.readn()...)
+		d.bdRead = false
+	}
+	d.bdRead = false
+	return bs
+}
+
+func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == cborBdNil || d.bd == cborBdUndefined {
+		d.bdRead = false
+		return nil
+	}
+	if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
+		d.bdRead = false
+		if bs == nil {
+			if zerocopy {
+				return d.decAppendIndefiniteBytes(d.d.b[:0])
+			}
+			return d.decAppendIndefiniteBytes(zeroByteSlice)
+		}
+		return d.decAppendIndefiniteBytes(bs[:0])
+	}
+	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
+	if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
+		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
+		return
+	}
+	clen := d.decLen()
+	d.bdRead = false
+	if zerocopy {
+		if d.br {
+			return d.r.readx(clen)
+		} else if len(bs) == 0 {
+			bs = d.d.b[:]
+		}
+	}
+	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
+}
+
+func (d *cborDecDriver) DecodeString() (s string) {
+	return string(d.DecodeBytes(d.d.b[:], true))
+}
+
+func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
+	return d.DecodeBytes(d.d.b[:], true)
+}
+
+func (d *cborDecDriver) DecodeTime() (t time.Time) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == cborBdNil || d.bd == cborBdUndefined {
+		d.bdRead = false
+		return
+	}
+	xtag := d.decUint()
+	d.bdRead = false
+	return d.decodeTime(xtag)
+}
+
+func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch xtag {
+	case 0:
+		var err error
+		if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
+			d.d.errorv(err)
+		}
+	case 1:
+		// decode an int64 or a float, and infer time.Time from there.
+		// for floats, round to microseconds, as that is what is guaranteed to fit well.
+		switch {
+		case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
+			f1, f2 := math.Modf(d.DecodeFloat64())
+			t = time.Unix(int64(f1), int64(f2*1e9))
+		case d.bd == cborBdFloat64:
+			f1, f2 := math.Modf(d.DecodeFloat64())
+			t = time.Unix(int64(f1), int64(f2*1e9))
+		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
+			d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
+			t = time.Unix(d.DecodeInt64(), 0)
+		default:
+			d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
+		}
+	default:
+		d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
+	}
+	t = t.UTC().Round(time.Microsecond)
+	return
+}
+
+func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	u := d.decUint()
+	d.bdRead = false
+	realxtag = u
+	if ext == nil {
+		re := rv.(*RawExt)
+		re.Tag = realxtag
+		d.d.decode(&re.Value)
+	} else if xtag != realxtag {
+		d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
+		return
+	} else {
+		var v interface{}
+		d.d.decode(&v)
+		ext.UpdateExt(rv, v)
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *cborDecDriver) DecodeNaked() {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+
+	n := d.d.n
+	var decodeFurther bool
+
+	switch d.bd {
+	case cborBdNil:
+		n.v = valueTypeNil
+	case cborBdFalse:
+		n.v = valueTypeBool
+		n.b = false
+	case cborBdTrue:
+		n.v = valueTypeBool
+		n.b = true
+	case cborBdFloat16, cborBdFloat32, cborBdFloat64:
+		n.v = valueTypeFloat
+		n.f = d.DecodeFloat64()
+	case cborBdIndefiniteBytes:
+		n.v = valueTypeBytes
+		n.l = d.DecodeBytes(nil, false)
+	case cborBdIndefiniteString:
+		n.v = valueTypeString
+		n.s = d.DecodeString()
+	case cborBdIndefiniteArray:
+		n.v = valueTypeArray
+		decodeFurther = true
+	case cborBdIndefiniteMap:
+		n.v = valueTypeMap
+		decodeFurther = true
+	default:
+		switch {
+		case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
+			if d.h.SignedInteger {
+				n.v = valueTypeInt
+				n.i = d.DecodeInt64()
+			} else {
+				n.v = valueTypeUint
+				n.u = d.DecodeUint64()
+			}
+		case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
+			n.v = valueTypeInt
+			n.i = d.DecodeInt64()
+		case d.bd >= cborBaseBytes && d.bd < cborBaseString:
+			n.v = valueTypeBytes
+			n.l = d.DecodeBytes(nil, false)
+		case d.bd >= cborBaseString && d.bd < cborBaseArray:
+			n.v = valueTypeString
+			n.s = d.DecodeString()
+		case d.bd >= cborBaseArray && d.bd < cborBaseMap:
+			n.v = valueTypeArray
+			decodeFurther = true
+		case d.bd >= cborBaseMap && d.bd < cborBaseTag:
+			n.v = valueTypeMap
+			decodeFurther = true
+		case d.bd >= cborBaseTag && d.bd < cborBaseSimple:
+			n.v = valueTypeExt
+			n.u = d.decUint()
+			n.l = nil
+			if n.u == 0 || n.u == 1 {
+				d.bdRead = false
+				n.v = valueTypeTime
+				n.t = d.decodeTime(n.u)
+			}
+			// d.bdRead = false
+			// d.d.decode(&re.Value) // handled by decode itself.
+			// decodeFurther = true
+		default:
+			d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
+			return
+		}
+	}
+
+	if !decodeFurther {
+		d.bdRead = false
+	}
+	return
+}
+
+// -------------------------
+
+// CborHandle is a Handle for the CBOR encoding format,
+// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
+//
+// CBOR is comprehensively supported, including support for:
+//   - indefinite-length arrays/maps/bytes/strings
+//   - (extension) tags in range 0..0xffff (0 .. 65535)
+//   - half, single and double-precision floats
+//   - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
+//   - nil, true, false, ...
+//   - arrays and maps, bytes and text strings
+//
+// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
+// Users can implement them as needed (using SetExt), including spec-documented ones:
+//   - timestamp, BigNum, BigFloat, Decimals,
+//   - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
+type CborHandle struct {
+	binaryEncodingType
+	noElemSeparators
+	BasicHandle
+
+	// IndefiniteLength=true, means that we encode using indefinitelength
+	IndefiniteLength bool
+
+	// TimeRFC3339 says to encode time.Time using RFC3339 format.
+	// If unset, we encode time.Time using seconds past epoch.
+	TimeRFC3339 bool
+
+	// _ [1]uint64 // padding
+}
+
+// Name returns the name of the handle: cbor
+func (h *CborHandle) Name() string { return "cbor" }
+
+// SetInterfaceExt sets an extension
+func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
+}
+
+func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
+	return &cborEncDriver{e: e, w: e.w, h: h}
+}
+
+func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
+	return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+}
+
+func (e *cborEncDriver) reset() {
+	e.w = e.e.w
+}
+
+func (d *cborDecDriver) reset() {
+	d.r, d.br = d.d.r, d.d.bytes
+	d.bd, d.bdRead = 0, false
+}
+
+var _ decDriver = (*cborDecDriver)(nil)
+var _ encDriver = (*cborEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/decode.go b/vendor/github.com/ugorji/go/codec/decode.go
new file mode 100644
index 0000000..1c0817a
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/decode.go
@@ -0,0 +1,2552 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"encoding"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+	"strconv"
+	"sync"
+	"time"
+)
+
+// Some tagging information for error messages.
+const (
+	msgBadDesc            = "unrecognized descriptor byte"
+	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
+)
+
+const decDefSliceCap = 8
+const decDefChanCap = 64 // should be large, as cap cannot be expanded
+const decScratchByteArrayLen = cacheLineSize - 8
+
+var (
+	errstrOnlyMapOrArrayCanDecodeIntoStruct = "only encoded map or array can be decoded into a struct"
+	errstrCannotDecodeIntoNil               = "cannot decode into nil"
+
+	errmsgExpandSliceOverflow     = "expand slice: slice overflow"
+	errmsgExpandSliceCannotChange = "expand slice: cannot change"
+
+	errDecoderNotInitialized = errors.New("Decoder not initialized")
+
+	errDecUnreadByteNothingToRead   = errors.New("cannot unread - nothing has been read")
+	errDecUnreadByteLastByteNotRead = errors.New("cannot unread - last byte has not been read")
+	errDecUnreadByteUnknown         = errors.New("cannot unread - reason unknown")
+)
+
+// decReader abstracts the reading source, allowing implementations that can
+// read from an io.Reader or directly off a byte slice with zero-copying.
+type decReader interface {
+	unreadn1()
+
+	// readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR
+	// just return a view of the []byte being decoded from.
+	// Ensure you call detachZeroCopyBytes later if this needs to be sent outside codec control.
+	readx(n int) []byte
+	readb([]byte)
+	readn1() uint8
+	numread() int // number of bytes read
+	track()
+	stopTrack() []byte
+
+	// skip will skip any byte that matches, and return the first non-matching byte
+	skip(accept *bitset256) (token byte)
+	// readTo will read any byte that matches, stopping once no-longer matching.
+	readTo(in []byte, accept *bitset256) (out []byte)
+	// readUntil will read, only stopping once it matches the 'stop' byte.
+	readUntil(in []byte, stop byte) (out []byte)
+}
+
+type decDriver interface {
+	// this will check if the next token is a break.
+	CheckBreak() bool
+	// Note: TryDecodeAsNil should be careful not to share any temporary []byte with
+	// the rest of the decDriver. This is because sometimes, we optimize by holding onto
+	// a transient []byte, and ensuring the only other call we make to the decDriver
+	// during that time is maybe a TryDecodeAsNil() call.
+	TryDecodeAsNil() bool
+	// vt is one of: Bytes, String, Nil, Slice or Map. Return unSet if not known.
+	ContainerType() (vt valueType)
+	// IsBuiltinType(rt uintptr) bool
+
+	// DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt.
+	// For maps and arrays, it will not do the decoding in-band, but will signal
+	// the decoder, so that is done later, by setting the decNaked.valueType field.
+	//
+	// Note: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
+	// for extensions, DecodeNaked must read the tag and the []byte if it exists.
+	// if the []byte is not read, then kInterfaceNaked will treat it as a Handle
+	// that stores the subsequent value in-band, and complete reading the RawExt.
+	//
+	// extensions should also use readx to decode them, for efficiency.
+	// kInterface will extract the detached byte slice if it has to pass it outside its realm.
+	DecodeNaked()
+
+	// Deprecated: use DecodeInt64 and DecodeUint64 instead
+	// DecodeInt(bitsize uint8) (i int64)
+	// DecodeUint(bitsize uint8) (ui uint64)
+
+	DecodeInt64() (i int64)
+	DecodeUint64() (ui uint64)
+
+	DecodeFloat64() (f float64)
+	DecodeBool() (b bool)
+	// DecodeString can also decode symbols.
+	// It looks redundant as DecodeBytes is available.
+	// However, some codecs (e.g. binc) support symbols and can
+	// return a pre-stored string value, meaning that it can bypass
+	// the cost of []byte->string conversion.
+	DecodeString() (s string)
+	DecodeStringAsBytes() (v []byte)
+
+	// DecodeBytes may be called directly, without going through reflection.
+	// Consequently, it must be designed to handle possible nil.
+	DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
+	// DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte)
+
+	// decodeExt will decode into a *RawExt or into an extension.
+	DecodeExt(v interface{}, xtag uint64, ext Ext) (realxtag uint64)
+	// decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
+
+	DecodeTime() (t time.Time)
+
+	ReadArrayStart() int
+	ReadArrayElem()
+	ReadArrayEnd()
+	ReadMapStart() int
+	ReadMapElemKey()
+	ReadMapElemValue()
+	ReadMapEnd()
+
+	reset()
+	uncacheRead()
+}
+
+type decDriverNoopContainerReader struct{}
+
+func (x decDriverNoopContainerReader) ReadArrayStart() (v int) { return }
+func (x decDriverNoopContainerReader) ReadArrayElem()          {}
+func (x decDriverNoopContainerReader) ReadArrayEnd()           {}
+func (x decDriverNoopContainerReader) ReadMapStart() (v int)   { return }
+func (x decDriverNoopContainerReader) ReadMapElemKey()         {}
+func (x decDriverNoopContainerReader) ReadMapElemValue()       {}
+func (x decDriverNoopContainerReader) ReadMapEnd()             {}
+func (x decDriverNoopContainerReader) CheckBreak() (v bool)    { return }
+
+// func (x decNoSeparator) uncacheRead() {}
+
+// DecodeOptions captures configuration options during decode.
+type DecodeOptions struct {
+	// MapType specifies type to use during schema-less decoding of a map in the stream.
+	// If nil (unset), we default to map[string]interface{} iff json handle and MapStringAsKey=true,
+	// else map[interface{}]interface{}.
+	MapType reflect.Type
+
+	// SliceType specifies type to use during schema-less decoding of an array in the stream.
+	// If nil (unset), we default to []interface{} for all formats.
+	SliceType reflect.Type
+
+	// MaxInitLen defines the maxinum initial length that we "make" a collection
+	// (string, slice, map, chan). If 0 or negative, we default to a sensible value
+	// based on the size of an element in the collection.
+	//
+	// For example, when decoding, a stream may say that it has 2^64 elements.
+	// We should not auto-matically provision a slice of that size, to prevent Out-Of-Memory crash.
+	// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
+	MaxInitLen int
+
+	// ReaderBufferSize is the size of the buffer used when reading.
+	//
+	// if > 0, we use a smart buffer internally for performance purposes.
+	ReaderBufferSize int
+
+	// If ErrorIfNoField, return an error when decoding a map
+	// from a codec stream into a struct, and no matching struct field is found.
+	ErrorIfNoField bool
+
+	// If ErrorIfNoArrayExpand, return an error when decoding a slice/array that cannot be expanded.
+	// For example, the stream contains an array of 8 items, but you are decoding into a [4]T array,
+	// or you are decoding into a slice of length 4 which is non-addressable (and so cannot be set).
+	ErrorIfNoArrayExpand bool
+
+	// If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64).
+	SignedInteger bool
+
+	// MapValueReset controls how we decode into a map value.
+	//
+	// By default, we MAY retrieve the mapping for a key, and then decode into that.
+	// However, especially with big maps, that retrieval may be expensive and unnecessary
+	// if the stream already contains all that is necessary to recreate the value.
+	//
+	// If true, we will never retrieve the previous mapping,
+	// but rather decode into a new value and set that in the map.
+	//
+	// If false, we will retrieve the previous mapping if necessary e.g.
+	// the previous mapping is a pointer, or is a struct or array with pre-set state,
+	// or is an interface.
+	MapValueReset bool
+
+	// SliceElementReset: on decoding a slice, reset the element to a zero value first.
+	//
+	// concern: if the slice already contained some garbage, we will decode into that garbage.
+	SliceElementReset bool
+
+	// InterfaceReset controls how we decode into an interface.
+	//
+	// By default, when we see a field that is an interface{...},
+	// or a map with interface{...} value, we will attempt decoding into the
+	// "contained" value.
+	//
+	// However, this prevents us from reading a string into an interface{}
+	// that formerly contained a number.
+	//
+	// If true, we will decode into a new "blank" value, and set that in the interface.
+	// If false, we will decode into whatever is contained in the interface.
+	InterfaceReset bool
+
+	// InternString controls interning of strings during decoding.
+	//
+	// Some handles, e.g. json, typically will read map keys as strings.
+	// If the set of keys are finite, it may help reduce allocation to
+	// look them up from a map (than to allocate them afresh).
+	//
+	// Note: Handles will be smart when using the intern functionality.
+	// Every string should not be interned.
+	// An excellent use-case for interning is struct field names,
+	// or map keys where key type is string.
+	InternString bool
+
+	// PreferArrayOverSlice controls whether to decode to an array or a slice.
+	//
+	// This only impacts decoding into a nil interface{}.
+	// Consequently, it has no effect on codecgen.
+	//
+	// *Note*: This only applies if using go1.5 and above,
+	// as it requires reflect.ArrayOf support which was absent before go1.5.
+	PreferArrayOverSlice bool
+
+	// DeleteOnNilMapValue controls how to decode a nil value in the stream.
+	//
+	// If true, we will delete the mapping of the key.
+	// Else, just set the mapping to the zero value of the type.
+	DeleteOnNilMapValue bool
+}
+
+// ------------------------------------
+
+type bufioDecReader struct {
+	buf []byte
+	r   io.Reader
+
+	c   int // cursor
+	n   int // num read
+	err error
+
+	tr  []byte
+	trb bool
+	b   [4]byte
+}
+
+func (z *bufioDecReader) reset(r io.Reader) {
+	z.r, z.c, z.n, z.err, z.trb = r, 0, 0, nil, false
+	if z.tr != nil {
+		z.tr = z.tr[:0]
+	}
+}
+
+func (z *bufioDecReader) Read(p []byte) (n int, err error) {
+	if z.err != nil {
+		return 0, z.err
+	}
+	p0 := p
+	n = copy(p, z.buf[z.c:])
+	z.c += n
+	if z.c == len(z.buf) {
+		z.c = 0
+	}
+	z.n += n
+	if len(p) == n {
+		if z.c == 0 {
+			z.buf = z.buf[:1]
+			z.buf[0] = p[len(p)-1]
+			z.c = 1
+		}
+		if z.trb {
+			z.tr = append(z.tr, p0[:n]...)
+		}
+		return
+	}
+	p = p[n:]
+	var n2 int
+	// if we are here, then z.buf is all read
+	if len(p) > len(z.buf) {
+		n2, err = decReadFull(z.r, p)
+		n += n2
+		z.n += n2
+		z.err = err
+		// don't return EOF if some bytes were read. keep for next time.
+		if n > 0 && err == io.EOF {
+			err = nil
+		}
+		// always keep last byte in z.buf
+		z.buf = z.buf[:1]
+		z.buf[0] = p[len(p)-1]
+		z.c = 1
+		if z.trb {
+			z.tr = append(z.tr, p0[:n]...)
+		}
+		return
+	}
+	// z.c is now 0, and len(p) <= len(z.buf)
+	for len(p) > 0 && z.err == nil {
+		// println("len(p) loop starting ... ")
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, err = z.r.Read(z.buf)
+		if n2 > 0 {
+			if err == io.EOF {
+				err = nil
+			}
+			z.buf = z.buf[:n2]
+			n2 = copy(p, z.buf)
+			z.c = n2
+			n += n2
+			z.n += n2
+			p = p[n2:]
+		}
+		z.err = err
+		// println("... len(p) loop done")
+	}
+	if z.c == 0 {
+		z.buf = z.buf[:1]
+		z.buf[0] = p[len(p)-1]
+		z.c = 1
+	}
+	if z.trb {
+		z.tr = append(z.tr, p0[:n]...)
+	}
+	return
+}
+
+func (z *bufioDecReader) ReadByte() (b byte, err error) {
+	z.b[0] = 0
+	_, err = z.Read(z.b[:1])
+	b = z.b[0]
+	return
+}
+
+func (z *bufioDecReader) UnreadByte() (err error) {
+	if z.err != nil {
+		return z.err
+	}
+	if z.c > 0 {
+		z.c--
+		z.n--
+		if z.trb {
+			z.tr = z.tr[:len(z.tr)-1]
+		}
+		return
+	}
+	return errDecUnreadByteNothingToRead
+}
+
+func (z *bufioDecReader) numread() int {
+	return z.n
+}
+
+func (z *bufioDecReader) readx(n int) (bs []byte) {
+	if n <= 0 || z.err != nil {
+		return
+	}
+	if z.c+n <= len(z.buf) {
+		bs = z.buf[z.c : z.c+n]
+		z.n += n
+		z.c += n
+		if z.trb {
+			z.tr = append(z.tr, bs...)
+		}
+		return
+	}
+	bs = make([]byte, n)
+	_, err := z.Read(bs)
+	if err != nil {
+		panic(err)
+	}
+	return
+}
+
+func (z *bufioDecReader) readb(bs []byte) {
+	_, err := z.Read(bs)
+	if err != nil {
+		panic(err)
+	}
+}
+
+// func (z *bufioDecReader) readn1eof() (b uint8, eof bool) {
+// 	b, err := z.ReadByte()
+// 	if err != nil {
+// 		if err == io.EOF {
+// 			eof = true
+// 		} else {
+// 			panic(err)
+// 		}
+// 	}
+// 	return
+// }
+
+func (z *bufioDecReader) readn1() (b uint8) {
+	b, err := z.ReadByte()
+	if err != nil {
+		panic(err)
+	}
+	return
+}
+
+func (z *bufioDecReader) search(in []byte, accept *bitset256, stop, flag uint8) (token byte, out []byte) {
+	// flag: 1 (skip), 2 (readTo), 4 (readUntil)
+	if flag == 4 {
+		for i := z.c; i < len(z.buf); i++ {
+			if z.buf[i] == stop {
+				token = z.buf[i]
+				z.n = z.n + (i - z.c) - 1
+				i++
+				out = z.buf[z.c:i]
+				if z.trb {
+					z.tr = append(z.tr, z.buf[z.c:i]...)
+				}
+				z.c = i
+				return
+			}
+		}
+	} else {
+		for i := z.c; i < len(z.buf); i++ {
+			if !accept.isset(z.buf[i]) {
+				token = z.buf[i]
+				z.n = z.n + (i - z.c) - 1
+				if flag == 1 {
+					i++
+				} else {
+					out = z.buf[z.c:i]
+				}
+				if z.trb {
+					z.tr = append(z.tr, z.buf[z.c:i]...)
+				}
+				z.c = i
+				return
+			}
+		}
+	}
+	z.n += len(z.buf) - z.c
+	if flag != 1 {
+		out = append(in, z.buf[z.c:]...)
+	}
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:]...)
+	}
+	var n2 int
+	if z.err != nil {
+		return
+	}
+	for {
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, z.err = z.r.Read(z.buf)
+		if n2 > 0 && z.err != nil {
+			z.err = nil
+		}
+		z.buf = z.buf[:n2]
+		if flag == 4 {
+			for i := 0; i < n2; i++ {
+				if z.buf[i] == stop {
+					token = z.buf[i]
+					z.n += i - 1
+					i++
+					out = append(out, z.buf[z.c:i]...)
+					if z.trb {
+						z.tr = append(z.tr, z.buf[z.c:i]...)
+					}
+					z.c = i
+					return
+				}
+			}
+		} else {
+			for i := 0; i < n2; i++ {
+				if !accept.isset(z.buf[i]) {
+					token = z.buf[i]
+					z.n += i - 1
+					if flag == 1 {
+						i++
+					}
+					if flag != 1 {
+						out = append(out, z.buf[z.c:i]...)
+					}
+					if z.trb {
+						z.tr = append(z.tr, z.buf[z.c:i]...)
+					}
+					z.c = i
+					return
+				}
+			}
+		}
+		if flag != 1 {
+			out = append(out, z.buf[:n2]...)
+		}
+		z.n += n2
+		if z.err != nil {
+			return
+		}
+		if z.trb {
+			z.tr = append(z.tr, z.buf[:n2]...)
+		}
+	}
+}
+
+func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
+	token, _ = z.search(nil, accept, 0, 1)
+	return
+}
+
+func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
+	_, out = z.search(in, accept, 0, 2)
+	return
+}
+
+func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
+	_, out = z.search(in, nil, stop, 4)
+	return
+}
+
+func (z *bufioDecReader) unreadn1() {
+	err := z.UnreadByte()
+	if err != nil {
+		panic(err)
+	}
+}
+
+func (z *bufioDecReader) track() {
+	if z.tr != nil {
+		z.tr = z.tr[:0]
+	}
+	z.trb = true
+}
+
+func (z *bufioDecReader) stopTrack() (bs []byte) {
+	z.trb = false
+	return z.tr
+}
+
+// ioDecReader is a decReader that reads off an io.Reader.
+//
+// It also has a fallback implementation of ByteScanner if needed.
+type ioDecReader struct {
+	r io.Reader // the reader passed in
+
+	rr io.Reader
+	br io.ByteScanner
+
+	l   byte // last byte
+	ls  byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
+	trb bool // tracking bytes turned on
+	_   bool
+	b   [4]byte // tiny buffer for reading single bytes
+
+	x  [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
+	n  int                       // num read
+	tr []byte                    // tracking bytes read
+}
+
+func (z *ioDecReader) reset(r io.Reader) {
+	z.r = r
+	z.rr = r
+	z.l, z.ls, z.n, z.trb = 0, 0, 0, false
+	if z.tr != nil {
+		z.tr = z.tr[:0]
+	}
+	var ok bool
+	if z.br, ok = r.(io.ByteScanner); !ok {
+		z.br = z
+		z.rr = z
+	}
+}
+
+func (z *ioDecReader) Read(p []byte) (n int, err error) {
+	if len(p) == 0 {
+		return
+	}
+	var firstByte bool
+	if z.ls == 1 {
+		z.ls = 2
+		p[0] = z.l
+		if len(p) == 1 {
+			n = 1
+			return
+		}
+		firstByte = true
+		p = p[1:]
+	}
+	n, err = z.r.Read(p)
+	if n > 0 {
+		if err == io.EOF && n == len(p) {
+			err = nil // read was successful, so postpone EOF (till next time)
+		}
+		z.l = p[n-1]
+		z.ls = 2
+	}
+	if firstByte {
+		n++
+	}
+	return
+}
+
+func (z *ioDecReader) ReadByte() (c byte, err error) {
+	n, err := z.Read(z.b[:1])
+	if n == 1 {
+		c = z.b[0]
+		if err == io.EOF {
+			err = nil // read was successful, so postpone EOF (till next time)
+		}
+	}
+	return
+}
+
+func (z *ioDecReader) UnreadByte() (err error) {
+	switch z.ls {
+	case 2:
+		z.ls = 1
+	case 0:
+		err = errDecUnreadByteNothingToRead
+	case 1:
+		err = errDecUnreadByteLastByteNotRead
+	default:
+		err = errDecUnreadByteUnknown
+	}
+	return
+}
+
+func (z *ioDecReader) numread() int {
+	return z.n
+}
+
+func (z *ioDecReader) readx(n int) (bs []byte) {
+	if n <= 0 {
+		return
+	}
+	if n < len(z.x) {
+		bs = z.x[:n]
+	} else {
+		bs = make([]byte, n)
+	}
+	if _, err := decReadFull(z.rr, bs); err != nil {
+		panic(err)
+	}
+	z.n += len(bs)
+	if z.trb {
+		z.tr = append(z.tr, bs...)
+	}
+	return
+}
+
+func (z *ioDecReader) readb(bs []byte) {
+	// if len(bs) == 0 {
+	// 	return
+	// }
+	if _, err := decReadFull(z.rr, bs); err != nil {
+		panic(err)
+	}
+	z.n += len(bs)
+	if z.trb {
+		z.tr = append(z.tr, bs...)
+	}
+}
+
+func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
+	b, err := z.br.ReadByte()
+	if err == nil {
+		z.n++
+		if z.trb {
+			z.tr = append(z.tr, b)
+		}
+	} else if err == io.EOF {
+		eof = true
+	} else {
+		panic(err)
+	}
+	return
+}
+
+func (z *ioDecReader) readn1() (b uint8) {
+	var err error
+	if b, err = z.br.ReadByte(); err == nil {
+		z.n++
+		if z.trb {
+			z.tr = append(z.tr, b)
+		}
+		return
+	}
+	panic(err)
+}
+
+func (z *ioDecReader) skip(accept *bitset256) (token byte) {
+	for {
+		var eof bool
+		token, eof = z.readn1eof()
+		if eof {
+			return
+		}
+		if accept.isset(token) {
+			continue
+		}
+		return
+	}
+}
+
+func (z *ioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
+	out = in
+	for {
+		token, eof := z.readn1eof()
+		if eof {
+			return
+		}
+		if accept.isset(token) {
+			out = append(out, token)
+		} else {
+			z.unreadn1()
+			return
+		}
+	}
+}
+
+func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
+	out = in
+	for {
+		token, eof := z.readn1eof()
+		if eof {
+			panic(io.EOF)
+		}
+		out = append(out, token)
+		if token == stop {
+			return
+		}
+	}
+}
+
+func (z *ioDecReader) unreadn1() {
+	err := z.br.UnreadByte()
+	if err != nil {
+		panic(err)
+	}
+	z.n--
+	if z.trb {
+		if l := len(z.tr) - 1; l >= 0 {
+			z.tr = z.tr[:l]
+		}
+	}
+}
+
+func (z *ioDecReader) track() {
+	if z.tr != nil {
+		z.tr = z.tr[:0]
+	}
+	z.trb = true
+}
+
+func (z *ioDecReader) stopTrack() (bs []byte) {
+	z.trb = false
+	return z.tr
+}
+
+// ------------------------------------
+
+var errBytesDecReaderCannotUnread = errors.New("cannot unread last byte read")
+
+// bytesDecReader is a decReader that reads off a byte slice with zero copying
+type bytesDecReader struct {
+	b []byte // data
+	c int    // cursor
+	a int    // available
+	t int    // track start
+}
+
+func (z *bytesDecReader) reset(in []byte) {
+	z.b = in
+	z.a = len(in)
+	z.c = 0
+	z.t = 0
+}
+
+func (z *bytesDecReader) numread() int {
+	return z.c
+}
+
+func (z *bytesDecReader) unreadn1() {
+	if z.c == 0 || len(z.b) == 0 {
+		panic(errBytesDecReaderCannotUnread)
+	}
+	z.c--
+	z.a++
+	return
+}
+
+func (z *bytesDecReader) readx(n int) (bs []byte) {
+	// slicing from a non-constant start position is more expensive,
+	// as more computation is required to decipher the pointer start position.
+	// However, we do it only once, and it's better than reslicing both z.b and return value.
+
+	if n <= 0 {
+	} else if z.a == 0 {
+		panic(io.EOF)
+	} else if n > z.a {
+		panic(io.ErrUnexpectedEOF)
+	} else {
+		c0 := z.c
+		z.c = c0 + n
+		z.a = z.a - n
+		bs = z.b[c0:z.c]
+	}
+	return
+}
+
+func (z *bytesDecReader) readb(bs []byte) {
+	copy(bs, z.readx(len(bs)))
+}
+
+func (z *bytesDecReader) readn1() (v uint8) {
+	if z.a == 0 {
+		panic(io.EOF)
+	}
+	v = z.b[z.c]
+	z.c++
+	z.a--
+	return
+}
+
+// func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
+// 	if z.a == 0 {
+// 		eof = true
+// 		return
+// 	}
+// 	v = z.b[z.c]
+// 	z.c++
+// 	z.a--
+// 	return
+// }
+
+func (z *bytesDecReader) skip(accept *bitset256) (token byte) {
+	if z.a == 0 {
+		return
+	}
+	blen := len(z.b)
+	for i := z.c; i < blen; i++ {
+		if !accept.isset(z.b[i]) {
+			token = z.b[i]
+			i++
+			z.a -= (i - z.c)
+			z.c = i
+			return
+		}
+	}
+	z.a, z.c = 0, blen
+	return
+}
+
+func (z *bytesDecReader) readTo(_ []byte, accept *bitset256) (out []byte) {
+	if z.a == 0 {
+		return
+	}
+	blen := len(z.b)
+	for i := z.c; i < blen; i++ {
+		if !accept.isset(z.b[i]) {
+			out = z.b[z.c:i]
+			z.a -= (i - z.c)
+			z.c = i
+			return
+		}
+	}
+	out = z.b[z.c:]
+	z.a, z.c = 0, blen
+	return
+}
+
+func (z *bytesDecReader) readUntil(_ []byte, stop byte) (out []byte) {
+	if z.a == 0 {
+		panic(io.EOF)
+	}
+	blen := len(z.b)
+	for i := z.c; i < blen; i++ {
+		if z.b[i] == stop {
+			i++
+			out = z.b[z.c:i]
+			z.a -= (i - z.c)
+			z.c = i
+			return
+		}
+	}
+	z.a, z.c = 0, blen
+	panic(io.EOF)
+}
+
+func (z *bytesDecReader) track() {
+	z.t = z.c
+}
+
+func (z *bytesDecReader) stopTrack() (bs []byte) {
+	return z.b[z.t:z.c]
+}
+
+// ----------------------------------------
+
+// func (d *Decoder) builtin(f *codecFnInfo, rv reflect.Value) {
+// 	d.d.DecodeBuiltin(f.ti.rtid, rv2i(rv))
+// }
+
+func (d *Decoder) rawExt(f *codecFnInfo, rv reflect.Value) {
+	d.d.DecodeExt(rv2i(rv), 0, nil)
+}
+
+func (d *Decoder) ext(f *codecFnInfo, rv reflect.Value) {
+	d.d.DecodeExt(rv2i(rv), f.xfTag, f.xfFn)
+}
+
+func (d *Decoder) selferUnmarshal(f *codecFnInfo, rv reflect.Value) {
+	rv2i(rv).(Selfer).CodecDecodeSelf(d)
+}
+
+func (d *Decoder) binaryUnmarshal(f *codecFnInfo, rv reflect.Value) {
+	bm := rv2i(rv).(encoding.BinaryUnmarshaler)
+	xbs := d.d.DecodeBytes(nil, true)
+	if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+func (d *Decoder) textUnmarshal(f *codecFnInfo, rv reflect.Value) {
+	tm := rv2i(rv).(encoding.TextUnmarshaler)
+	fnerr := tm.UnmarshalText(d.d.DecodeStringAsBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+func (d *Decoder) jsonUnmarshal(f *codecFnInfo, rv reflect.Value) {
+	tm := rv2i(rv).(jsonUnmarshaler)
+	// bs := d.d.DecodeBytes(d.b[:], true, true)
+	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
+	fnerr := tm.UnmarshalJSON(d.nextValueBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+func (d *Decoder) kErr(f *codecFnInfo, rv reflect.Value) {
+	d.errorf("no decoding function defined for kind %v", rv.Kind())
+}
+
+// var kIntfCtr uint64
+
+func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
+	// nil interface:
+	// use some hieristics to decode it appropriately
+	// based on the detected next value in the stream.
+	n := d.naked()
+	d.d.DecodeNaked()
+	if n.v == valueTypeNil {
+		return
+	}
+	// We cannot decode non-nil stream value into nil interface with methods (e.g. io.Reader).
+	if f.ti.numMeth > 0 {
+		d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, f.ti.numMeth)
+		return
+	}
+	// var useRvn bool
+	switch n.v {
+	case valueTypeMap:
+		// if json, default to a map type with string keys
+		mtid := d.mtid
+		if mtid == 0 {
+			if d.jsms {
+				mtid = mapStrIntfTypId
+			} else {
+				mtid = mapIntfIntfTypId
+			}
+		}
+		if mtid == mapIntfIntfTypId {
+			n.initContainers()
+			if n.lm < arrayCacheLen {
+				n.ma[n.lm] = nil
+				rvn = n.rma[n.lm]
+				n.lm++
+				d.decode(&n.ma[n.lm-1])
+				n.lm--
+			} else {
+				var v2 map[interface{}]interface{}
+				d.decode(&v2)
+				rvn = reflect.ValueOf(&v2).Elem()
+			}
+		} else if mtid == mapStrIntfTypId { // for json performance
+			n.initContainers()
+			if n.ln < arrayCacheLen {
+				n.na[n.ln] = nil
+				rvn = n.rna[n.ln]
+				n.ln++
+				d.decode(&n.na[n.ln-1])
+				n.ln--
+			} else {
+				var v2 map[string]interface{}
+				d.decode(&v2)
+				rvn = reflect.ValueOf(&v2).Elem()
+			}
+		} else {
+			if d.mtr {
+				rvn = reflect.New(d.h.MapType)
+				d.decode(rv2i(rvn))
+				rvn = rvn.Elem()
+			} else {
+				rvn = reflect.New(d.h.MapType).Elem()
+				d.decodeValue(rvn, nil, true)
+			}
+		}
+	case valueTypeArray:
+		if d.stid == 0 || d.stid == intfSliceTypId {
+			n.initContainers()
+			if n.ls < arrayCacheLen {
+				n.sa[n.ls] = nil
+				rvn = n.rsa[n.ls]
+				n.ls++
+				d.decode(&n.sa[n.ls-1])
+				n.ls--
+			} else {
+				var v2 []interface{}
+				d.decode(&v2)
+				rvn = reflect.ValueOf(&v2).Elem()
+			}
+			if reflectArrayOfSupported && d.stid == 0 && d.h.PreferArrayOverSlice {
+				rvn2 := reflect.New(reflectArrayOf(rvn.Len(), intfTyp)).Elem()
+				reflect.Copy(rvn2, rvn)
+				rvn = rvn2
+			}
+		} else {
+			if d.str {
+				rvn = reflect.New(d.h.SliceType)
+				d.decode(rv2i(rvn))
+				rvn = rvn.Elem()
+			} else {
+				rvn = reflect.New(d.h.SliceType).Elem()
+				d.decodeValue(rvn, nil, true)
+			}
+		}
+	case valueTypeExt:
+		var v interface{}
+		tag, bytes := n.u, n.l // calling decode below might taint the values
+		if bytes == nil {
+			n.initContainers()
+			if n.li < arrayCacheLen {
+				n.ia[n.li] = nil
+				n.li++
+				d.decode(&n.ia[n.li-1])
+				// v = *(&n.ia[l])
+				n.li--
+				v = n.ia[n.li]
+				n.ia[n.li] = nil
+			} else {
+				d.decode(&v)
+			}
+		}
+		bfn := d.h.getExtForTag(tag)
+		if bfn == nil {
+			var re RawExt
+			re.Tag = tag
+			re.Data = detachZeroCopyBytes(d.bytes, nil, bytes)
+			re.Value = v
+			rvn = reflect.ValueOf(&re).Elem()
+		} else {
+			rvnA := reflect.New(bfn.rt)
+			if bytes != nil {
+				bfn.ext.ReadExt(rv2i(rvnA), bytes)
+			} else {
+				bfn.ext.UpdateExt(rv2i(rvnA), v)
+			}
+			rvn = rvnA.Elem()
+		}
+	case valueTypeNil:
+		// no-op
+	case valueTypeInt:
+		rvn = n.ri
+	case valueTypeUint:
+		rvn = n.ru
+	case valueTypeFloat:
+		rvn = n.rf
+	case valueTypeBool:
+		rvn = n.rb
+	case valueTypeString, valueTypeSymbol:
+		rvn = n.rs
+	case valueTypeBytes:
+		rvn = n.rl
+	case valueTypeTime:
+		rvn = n.rt
+	default:
+		panicv.errorf("kInterfaceNaked: unexpected valueType: %d", n.v)
+	}
+	return
+}
+
+func (d *Decoder) kInterface(f *codecFnInfo, rv reflect.Value) {
+	// Note:
+	// A consequence of how kInterface works, is that
+	// if an interface already contains something, we try
+	// to decode into what was there before.
+	// We do not replace with a generic value (as got from decodeNaked).
+
+	// every interface passed here MUST be settable.
+	var rvn reflect.Value
+	if rv.IsNil() || d.h.InterfaceReset {
+		// check if mapping to a type: if so, initialize it and move on
+		rvn = d.h.intf2impl(f.ti.rtid)
+		if rvn.IsValid() {
+			rv.Set(rvn)
+		} else {
+			rvn = d.kInterfaceNaked(f)
+			if rvn.IsValid() {
+				rv.Set(rvn)
+			} else if d.h.InterfaceReset {
+				// reset to zero value based on current type in there.
+				rv.Set(reflect.Zero(rv.Elem().Type()))
+			}
+			return
+		}
+	} else {
+		// now we have a non-nil interface value, meaning it contains a type
+		rvn = rv.Elem()
+	}
+	if d.d.TryDecodeAsNil() {
+		rv.Set(reflect.Zero(rvn.Type()))
+		return
+	}
+
+	// Note: interface{} is settable, but underlying type may not be.
+	// Consequently, we MAY have to create a decodable value out of the underlying value,
+	// decode into it, and reset the interface itself.
+	// fmt.Printf(">>>> kInterface: rvn type: %v, rv type: %v\n", rvn.Type(), rv.Type())
+
+	rvn2, canDecode := isDecodeable(rvn)
+	if canDecode {
+		d.decodeValue(rvn2, nil, true)
+		return
+	}
+
+	rvn2 = reflect.New(rvn.Type()).Elem()
+	rvn2.Set(rvn)
+	d.decodeValue(rvn2, nil, true)
+	rv.Set(rvn2)
+}
+
+func decStructFieldKey(dd decDriver, keyType valueType, b *[decScratchByteArrayLen]byte) (rvkencname []byte) {
+	// use if-else-if, not switch (which compiles to binary-search)
+	// since keyType is typically valueTypeString, branch prediction is pretty good.
+
+	if keyType == valueTypeString {
+		rvkencname = dd.DecodeStringAsBytes()
+	} else if keyType == valueTypeInt {
+		rvkencname = strconv.AppendInt(b[:0], dd.DecodeInt64(), 10)
+	} else if keyType == valueTypeUint {
+		rvkencname = strconv.AppendUint(b[:0], dd.DecodeUint64(), 10)
+	} else if keyType == valueTypeFloat {
+		rvkencname = strconv.AppendFloat(b[:0], dd.DecodeFloat64(), 'f', -1, 64)
+	} else {
+		rvkencname = dd.DecodeStringAsBytes()
+	}
+	return rvkencname
+}
+
+func (d *Decoder) kStruct(f *codecFnInfo, rv reflect.Value) {
+	fti := f.ti
+	dd := d.d
+	elemsep := d.esep
+	sfn := structFieldNode{v: rv, update: true}
+	ctyp := dd.ContainerType()
+	if ctyp == valueTypeMap {
+		containerLen := dd.ReadMapStart()
+		if containerLen == 0 {
+			dd.ReadMapEnd()
+			return
+		}
+		tisfi := fti.sfiSort
+		hasLen := containerLen >= 0
+
+		var rvkencname []byte
+		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+			if elemsep {
+				dd.ReadMapElemKey()
+			}
+			rvkencname = decStructFieldKey(dd, fti.keyType, &d.b)
+			if elemsep {
+				dd.ReadMapElemValue()
+			}
+			if k := fti.indexForEncName(rvkencname); k > -1 {
+				si := tisfi[k]
+				if dd.TryDecodeAsNil() {
+					si.setToZeroValue(rv)
+				} else {
+					d.decodeValue(sfn.field(si), nil, true)
+				}
+			} else {
+				d.structFieldNotFound(-1, stringView(rvkencname))
+			}
+			// keepAlive4StringView(rvkencnameB) // not needed, as reference is outside loop
+		}
+		dd.ReadMapEnd()
+	} else if ctyp == valueTypeArray {
+		containerLen := dd.ReadArrayStart()
+		if containerLen == 0 {
+			dd.ReadArrayEnd()
+			return
+		}
+		// Not much gain from doing it two ways for array.
+		// Arrays are not used as much for structs.
+		hasLen := containerLen >= 0
+		for j, si := range fti.sfiSrc {
+			if (hasLen && j == containerLen) || (!hasLen && dd.CheckBreak()) {
+				break
+			}
+			if elemsep {
+				dd.ReadArrayElem()
+			}
+			if dd.TryDecodeAsNil() {
+				si.setToZeroValue(rv)
+			} else {
+				d.decodeValue(sfn.field(si), nil, true)
+			}
+		}
+		if containerLen > len(fti.sfiSrc) {
+			// read remaining values and throw away
+			for j := len(fti.sfiSrc); j < containerLen; j++ {
+				if elemsep {
+					dd.ReadArrayElem()
+				}
+				d.structFieldNotFound(j, "")
+			}
+		}
+		dd.ReadArrayEnd()
+	} else {
+		d.errorstr(errstrOnlyMapOrArrayCanDecodeIntoStruct)
+		return
+	}
+}
+
+func (d *Decoder) kSlice(f *codecFnInfo, rv reflect.Value) {
+	// A slice can be set from a map or array in stream.
+	// This way, the order can be kept (as order is lost with map).
+	ti := f.ti
+	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.SendDir) == 0 {
+		d.errorf("receive-only channel cannot be decoded")
+	}
+	dd := d.d
+	rtelem0 := ti.elem
+	ctyp := dd.ContainerType()
+	if ctyp == valueTypeBytes || ctyp == valueTypeString {
+		// you can only decode bytes or string in the stream into a slice or array of bytes
+		if !(ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8) {
+			d.errorf("bytes/string in stream must decode into slice/array of bytes, not %v", ti.rt)
+		}
+		if f.seq == seqTypeChan {
+			bs2 := dd.DecodeBytes(nil, true)
+			irv := rv2i(rv)
+			ch, ok := irv.(chan<- byte)
+			if !ok {
+				ch = irv.(chan byte)
+			}
+			for _, b := range bs2 {
+				ch <- b
+			}
+		} else {
+			rvbs := rv.Bytes()
+			bs2 := dd.DecodeBytes(rvbs, false)
+			// if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) {
+			if !(len(bs2) > 0 && len(bs2) == len(rvbs) && &bs2[0] == &rvbs[0]) {
+				if rv.CanSet() {
+					rv.SetBytes(bs2)
+				} else if len(rvbs) > 0 && len(bs2) > 0 {
+					copy(rvbs, bs2)
+				}
+			}
+		}
+		return
+	}
+
+	// array := f.seq == seqTypeChan
+
+	slh, containerLenS := d.decSliceHelperStart() // only expects valueType(Array|Map)
+
+	// an array can never return a nil slice. so no need to check f.array here.
+	if containerLenS == 0 {
+		if rv.CanSet() {
+			if f.seq == seqTypeSlice {
+				if rv.IsNil() {
+					rv.Set(reflect.MakeSlice(ti.rt, 0, 0))
+				} else {
+					rv.SetLen(0)
+				}
+			} else if f.seq == seqTypeChan {
+				if rv.IsNil() {
+					rv.Set(reflect.MakeChan(ti.rt, 0))
+				}
+			}
+		}
+		slh.End()
+		return
+	}
+
+	rtelem0Size := int(rtelem0.Size())
+	rtElem0Kind := rtelem0.Kind()
+	rtelem0Mut := !isImmutableKind(rtElem0Kind)
+	rtelem := rtelem0
+	rtelemkind := rtelem.Kind()
+	for rtelemkind == reflect.Ptr {
+		rtelem = rtelem.Elem()
+		rtelemkind = rtelem.Kind()
+	}
+
+	var fn *codecFn
+
+	var rvCanset = rv.CanSet()
+	var rvChanged bool
+	var rv0 = rv
+	var rv9 reflect.Value
+
+	rvlen := rv.Len()
+	rvcap := rv.Cap()
+	hasLen := containerLenS > 0
+	if hasLen && f.seq == seqTypeSlice {
+		if containerLenS > rvcap {
+			oldRvlenGtZero := rvlen > 0
+			rvlen = decInferLen(containerLenS, d.h.MaxInitLen, int(rtelem0.Size()))
+			if rvlen <= rvcap {
+				if rvCanset {
+					rv.SetLen(rvlen)
+				}
+			} else if rvCanset {
+				rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
+				rvcap = rvlen
+				rvChanged = true
+			} else {
+				d.errorf("cannot decode into non-settable slice")
+			}
+			if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) {
+				reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap)
+			}
+		} else if containerLenS != rvlen {
+			rvlen = containerLenS
+			if rvCanset {
+				rv.SetLen(rvlen)
+			}
+			// else {
+			// rv = rv.Slice(0, rvlen)
+			// rvChanged = true
+			// d.errorf("cannot decode into non-settable slice")
+			// }
+		}
+	}
+
+	// consider creating new element once, and just decoding into it.
+	var rtelem0Zero reflect.Value
+	var rtelem0ZeroValid bool
+	var decodeAsNil bool
+	var j int
+	d.cfer()
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && (f.seq == seqTypeSlice || f.seq == seqTypeChan) && rv.IsNil() {
+			if hasLen {
+				rvlen = decInferLen(containerLenS, d.h.MaxInitLen, rtelem0Size)
+			} else if f.seq == seqTypeSlice {
+				rvlen = decDefSliceCap
+			} else {
+				rvlen = decDefChanCap
+			}
+			if rvCanset {
+				if f.seq == seqTypeSlice {
+					rv = reflect.MakeSlice(ti.rt, rvlen, rvlen)
+					rvChanged = true
+				} else { // chan
+					// xdebugf(">>>>>> haslen = %v, make chan of type '%v' with length: %v", hasLen, ti.rt, rvlen)
+					rv = reflect.MakeChan(ti.rt, rvlen)
+					rvChanged = true
+				}
+			} else {
+				d.errorf("cannot decode into non-settable slice")
+			}
+		}
+		slh.ElemContainerState(j)
+		decodeAsNil = dd.TryDecodeAsNil()
+		if f.seq == seqTypeChan {
+			if decodeAsNil {
+				rv.Send(reflect.Zero(rtelem0))
+				continue
+			}
+			if rtelem0Mut || !rv9.IsValid() { // || (rtElem0Kind == reflect.Ptr && rv9.IsNil()) {
+				rv9 = reflect.New(rtelem0).Elem()
+			}
+			if fn == nil {
+				fn = d.cf.get(rtelem, true, true)
+			}
+			d.decodeValue(rv9, fn, true)
+			// xdebugf(">>>> rv9 sent on %v during decode: %v, with len=%v, cap=%v", rv.Type(), rv9, rv.Len(), rv.Cap())
+			rv.Send(rv9)
+		} else {
+			// if indefinite, etc, then expand the slice if necessary
+			var decodeIntoBlank bool
+			if j >= rvlen {
+				if f.seq == seqTypeArray {
+					d.arrayCannotExpand(rvlen, j+1)
+					decodeIntoBlank = true
+				} else { // if f.seq == seqTypeSlice
+					// rv = reflect.Append(rv, reflect.Zero(rtelem0)) // append logic + varargs
+					var rvcap2 int
+					var rvErrmsg2 string
+					rv9, rvcap2, rvChanged, rvErrmsg2 =
+						expandSliceRV(rv, ti.rt, rvCanset, rtelem0Size, 1, rvlen, rvcap)
+					if rvErrmsg2 != "" {
+						d.errorf(rvErrmsg2)
+					}
+					rvlen++
+					if rvChanged {
+						rv = rv9
+						rvcap = rvcap2
+					}
+				}
+			}
+			if decodeIntoBlank {
+				if !decodeAsNil {
+					d.swallow()
+				}
+			} else {
+				rv9 = rv.Index(j)
+				if d.h.SliceElementReset || decodeAsNil {
+					if !rtelem0ZeroValid {
+						rtelem0ZeroValid = true
+						rtelem0Zero = reflect.Zero(rtelem0)
+					}
+					rv9.Set(rtelem0Zero)
+				}
+				if decodeAsNil {
+					continue
+				}
+
+				if fn == nil {
+					fn = d.cf.get(rtelem, true, true)
+				}
+				d.decodeValue(rv9, fn, true)
+			}
+		}
+	}
+	if f.seq == seqTypeSlice {
+		if j < rvlen {
+			if rv.CanSet() {
+				rv.SetLen(j)
+			} else if rvCanset {
+				rv = rv.Slice(0, j)
+				rvChanged = true
+			} // else { d.errorf("kSlice: cannot change non-settable slice") }
+			rvlen = j
+		} else if j == 0 && rv.IsNil() {
+			if rvCanset {
+				rv = reflect.MakeSlice(ti.rt, 0, 0)
+				rvChanged = true
+			} // else { d.errorf("kSlice: cannot change non-settable slice") }
+		}
+	}
+	slh.End()
+
+	if rvChanged { // infers rvCanset=true, so it can be reset
+		rv0.Set(rv)
+	}
+}
+
+// func (d *Decoder) kArray(f *codecFnInfo, rv reflect.Value) {
+// 	// d.decodeValueFn(rv.Slice(0, rv.Len()))
+// 	f.kSlice(rv.Slice(0, rv.Len()))
+// }
+
+func (d *Decoder) kMap(f *codecFnInfo, rv reflect.Value) {
+	dd := d.d
+	containerLen := dd.ReadMapStart()
+	elemsep := d.esep
+	ti := f.ti
+	if rv.IsNil() {
+		rv.Set(makeMapReflect(ti.rt, containerLen))
+	}
+
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return
+	}
+
+	ktype, vtype := ti.key, ti.elem
+	ktypeId := rt2id(ktype)
+	vtypeKind := vtype.Kind()
+
+	var keyFn, valFn *codecFn
+	var ktypeLo, vtypeLo reflect.Type
+
+	for ktypeLo = ktype; ktypeLo.Kind() == reflect.Ptr; ktypeLo = ktypeLo.Elem() {
+	}
+
+	for vtypeLo = vtype; vtypeLo.Kind() == reflect.Ptr; vtypeLo = vtypeLo.Elem() {
+	}
+
+	var mapGet, mapSet bool
+	rvvImmut := isImmutableKind(vtypeKind)
+	if !d.h.MapValueReset {
+		// if pointer, mapGet = true
+		// if interface, mapGet = true if !DecodeNakedAlways (else false)
+		// if builtin, mapGet = false
+		// else mapGet = true
+		if vtypeKind == reflect.Ptr {
+			mapGet = true
+		} else if vtypeKind == reflect.Interface {
+			if !d.h.InterfaceReset {
+				mapGet = true
+			}
+		} else if !rvvImmut {
+			mapGet = true
+		}
+	}
+
+	var rvk, rvkp, rvv, rvz reflect.Value
+	rvkMut := !isImmutableKind(ktype.Kind()) // if ktype is immutable, then re-use the same rvk.
+	ktypeIsString := ktypeId == stringTypId
+	ktypeIsIntf := ktypeId == intfTypId
+	hasLen := containerLen > 0
+	var kstrbs []byte
+	d.cfer()
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if rvkMut || !rvkp.IsValid() {
+			rvkp = reflect.New(ktype)
+			rvk = rvkp.Elem()
+		}
+		if elemsep {
+			dd.ReadMapElemKey()
+		}
+		if false && dd.TryDecodeAsNil() { // nil cannot be a map key, so disregard this block
+			// Previously, if a nil key, we just ignored the mapped value and continued.
+			// However, that makes the result of encoding and then decoding map[intf]intf{nil:nil}
+			// to be an empty map.
+			// Instead, we treat a nil key as the zero value of the type.
+			rvk.Set(reflect.Zero(ktype))
+		} else if ktypeIsString {
+			kstrbs = dd.DecodeStringAsBytes()
+			rvk.SetString(stringView(kstrbs))
+			// NOTE: if doing an insert, you MUST use a real string (not stringview)
+		} else {
+			if keyFn == nil {
+				keyFn = d.cf.get(ktypeLo, true, true)
+			}
+			d.decodeValue(rvk, keyFn, true)
+		}
+		// special case if a byte array.
+		if ktypeIsIntf {
+			if rvk2 := rvk.Elem(); rvk2.IsValid() {
+				if rvk2.Type() == uint8SliceTyp {
+					rvk = reflect.ValueOf(d.string(rvk2.Bytes()))
+				} else {
+					rvk = rvk2
+				}
+			}
+		}
+
+		if elemsep {
+			dd.ReadMapElemValue()
+		}
+
+		// Brittle, but OK per TryDecodeAsNil() contract.
+		// i.e. TryDecodeAsNil never shares slices with other decDriver procedures
+		if dd.TryDecodeAsNil() {
+			if ktypeIsString {
+				rvk.SetString(d.string(kstrbs))
+			}
+			if d.h.DeleteOnNilMapValue {
+				rv.SetMapIndex(rvk, reflect.Value{})
+			} else {
+				rv.SetMapIndex(rvk, reflect.Zero(vtype))
+			}
+			continue
+		}
+
+		mapSet = true // set to false if u do a get, and its a non-nil pointer
+		if mapGet {
+			// mapGet true only in case where kind=Ptr|Interface or kind is otherwise mutable.
+			rvv = rv.MapIndex(rvk)
+			if !rvv.IsValid() {
+				rvv = reflect.New(vtype).Elem()
+			} else if vtypeKind == reflect.Ptr {
+				if rvv.IsNil() {
+					rvv = reflect.New(vtype).Elem()
+				} else {
+					mapSet = false
+				}
+			} else if vtypeKind == reflect.Interface {
+				// not addressable, and thus not settable.
+				// e MUST create a settable/addressable variant
+				rvv2 := reflect.New(rvv.Type()).Elem()
+				if !rvv.IsNil() {
+					rvv2.Set(rvv)
+				}
+				rvv = rvv2
+			}
+			// else it is ~mutable, and we can just decode into it directly
+		} else if rvvImmut {
+			if !rvz.IsValid() {
+				rvz = reflect.New(vtype).Elem()
+			}
+			rvv = rvz
+		} else {
+			rvv = reflect.New(vtype).Elem()
+		}
+
+		// We MUST be done with the stringview of the key, before decoding the value
+		// so that we don't bastardize the reused byte array.
+		if mapSet && ktypeIsString {
+			rvk.SetString(d.string(kstrbs))
+		}
+		if valFn == nil {
+			valFn = d.cf.get(vtypeLo, true, true)
+		}
+		d.decodeValue(rvv, valFn, true)
+		// d.decodeValueFn(rvv, valFn)
+		if mapSet {
+			rv.SetMapIndex(rvk, rvv)
+		}
+		// if ktypeIsString {
+		// 	// keepAlive4StringView(kstrbs) // not needed, as reference is outside loop
+		// }
+	}
+
+	dd.ReadMapEnd()
+}
+
+// decNaked is used to keep track of the primitives decoded.
+// Without it, we would have to decode each primitive and wrap it
+// in an interface{}, causing an allocation.
+// In this model, the primitives are decoded in a "pseudo-atomic" fashion,
+// so we can rest assured that no other decoding happens while these
+// primitives are being decoded.
+//
+// maps and arrays are not handled by this mechanism.
+// However, RawExt is, and we accommodate for extensions that decode
+// RawExt from DecodeNaked, but need to decode the value subsequently.
+// kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat.
+//
+// However, decNaked also keeps some arrays of default maps and slices
+// used in DecodeNaked. This way, we can get a pointer to it
+// without causing a new heap allocation.
+//
+// kInterfaceNaked will ensure that there is no allocation for the common
+// uses.
+
+type decNakedContainers struct {
+	// array/stacks for reducing allocation
+	// keep arrays at the bottom? Chance is that they are not used much.
+	ia [arrayCacheLen]interface{}
+	ma [arrayCacheLen]map[interface{}]interface{}
+	na [arrayCacheLen]map[string]interface{}
+	sa [arrayCacheLen][]interface{}
+
+	// ria [arrayCacheLen]reflect.Value // not needed, as we decode directly into &ia[n]
+	rma, rna, rsa [arrayCacheLen]reflect.Value // reflect.Value mapping to above
+}
+
+func (n *decNakedContainers) init() {
+	for i := 0; i < arrayCacheLen; i++ {
+		// n.ria[i] = reflect.ValueOf(&(n.ia[i])).Elem()
+		n.rma[i] = reflect.ValueOf(&(n.ma[i])).Elem()
+		n.rna[i] = reflect.ValueOf(&(n.na[i])).Elem()
+		n.rsa[i] = reflect.ValueOf(&(n.sa[i])).Elem()
+	}
+}
+
+type decNaked struct {
+	// r RawExt // used for RawExt, uint, []byte.
+
+	// primitives below
+	u uint64
+	i int64
+	f float64
+	l []byte
+	s string
+
+	// ---- cpu cache line boundary?
+	t time.Time
+	b bool
+
+	// state
+	v              valueType
+	li, lm, ln, ls int8
+	inited         bool
+
+	*decNakedContainers
+
+	ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
+
+	// _ [6]uint64 // padding // no padding - rt goes into next cache line
+}
+
+func (n *decNaked) init() {
+	if n.inited {
+		return
+	}
+	n.ru = reflect.ValueOf(&n.u).Elem()
+	n.ri = reflect.ValueOf(&n.i).Elem()
+	n.rf = reflect.ValueOf(&n.f).Elem()
+	n.rl = reflect.ValueOf(&n.l).Elem()
+	n.rs = reflect.ValueOf(&n.s).Elem()
+	n.rt = reflect.ValueOf(&n.t).Elem()
+	n.rb = reflect.ValueOf(&n.b).Elem()
+
+	n.inited = true
+	// n.rr[] = reflect.ValueOf(&n.)
+}
+
+func (n *decNaked) initContainers() {
+	if n.decNakedContainers == nil {
+		n.decNakedContainers = new(decNakedContainers)
+		n.decNakedContainers.init()
+	}
+}
+
+func (n *decNaked) reset() {
+	if n == nil {
+		return
+	}
+	n.li, n.lm, n.ln, n.ls = 0, 0, 0, 0
+}
+
+type rtid2rv struct {
+	rtid uintptr
+	rv   reflect.Value
+}
+
+// --------------
+
+type decReaderSwitch struct {
+	rb bytesDecReader
+	// ---- cpu cache line boundary?
+	ri       *ioDecReader
+	mtr, str bool // whether maptype or slicetype are known types
+
+	be    bool // is binary encoding
+	bytes bool // is bytes reader
+	js    bool // is json handle
+	jsms  bool // is json handle, and MapKeyAsString
+	esep  bool // has elem separators
+}
+
+// TODO: Uncomment after mid-stack inlining enabled in go 1.11
+//
+// func (z *decReaderSwitch) unreadn1() {
+// 	if z.bytes {
+// 		z.rb.unreadn1()
+// 	} else {
+// 		z.ri.unreadn1()
+// 	}
+// }
+// func (z *decReaderSwitch) readx(n int) []byte {
+// 	if z.bytes {
+// 		return z.rb.readx(n)
+// 	}
+// 	return z.ri.readx(n)
+// }
+// func (z *decReaderSwitch) readb(s []byte) {
+// 	if z.bytes {
+// 		z.rb.readb(s)
+// 	} else {
+// 		z.ri.readb(s)
+// 	}
+// }
+// func (z *decReaderSwitch) readn1() uint8 {
+// 	if z.bytes {
+// 		return z.rb.readn1()
+// 	}
+// 	return z.ri.readn1()
+// }
+// func (z *decReaderSwitch) numread() int {
+// 	if z.bytes {
+// 		return z.rb.numread()
+// 	}
+// 	return z.ri.numread()
+// }
+// func (z *decReaderSwitch) track() {
+// 	if z.bytes {
+// 		z.rb.track()
+// 	} else {
+// 		z.ri.track()
+// 	}
+// }
+// func (z *decReaderSwitch) stopTrack() []byte {
+// 	if z.bytes {
+// 		return z.rb.stopTrack()
+// 	}
+// 	return z.ri.stopTrack()
+// }
+// func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
+// 	if z.bytes {
+// 		return z.rb.skip(accept)
+// 	}
+// 	return z.ri.skip(accept)
+// }
+// func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
+// 	if z.bytes {
+// 		return z.rb.readTo(in, accept)
+// 	}
+// 	return z.ri.readTo(in, accept)
+// }
+// func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
+// 	if z.bytes {
+// 		return z.rb.readUntil(in, stop)
+// 	}
+// 	return z.ri.readUntil(in, stop)
+// }
+
+// A Decoder reads and decodes an object from an input stream in the codec format.
+type Decoder struct {
+	panicHdl
+	// hopefully, reduce derefencing cost by laying the decReader inside the Decoder.
+	// Try to put things that go together to fit within a cache line (8 words).
+
+	d decDriver
+	// NOTE: Decoder shouldn't call it's read methods,
+	// as the handler MAY need to do some coordination.
+	r  decReader
+	h  *BasicHandle
+	bi *bufioDecReader
+	// cache the mapTypeId and sliceTypeId for faster comparisons
+	mtid uintptr
+	stid uintptr
+
+	// ---- cpu cache line boundary?
+	decReaderSwitch
+
+	// ---- cpu cache line boundary?
+	codecFnPooler
+	// cr containerStateRecv
+	n   *decNaked
+	nsp *sync.Pool
+	err error
+
+	// ---- cpu cache line boundary?
+	b  [decScratchByteArrayLen]byte // scratch buffer, used by Decoder and xxxEncDrivers
+	is map[string]string            // used for interning strings
+
+	// padding - false sharing help // modify 232 if Decoder struct changes.
+	// _ [cacheLineSize - 232%cacheLineSize]byte
+}
+
+// NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
+//
+// For efficiency, Users are encouraged to pass in a memory buffered reader
+// (eg bufio.Reader, bytes.Buffer).
+func NewDecoder(r io.Reader, h Handle) *Decoder {
+	d := newDecoder(h)
+	d.Reset(r)
+	return d
+}
+
+// NewDecoderBytes returns a Decoder which efficiently decodes directly
+// from a byte slice with zero copying.
+func NewDecoderBytes(in []byte, h Handle) *Decoder {
+	d := newDecoder(h)
+	d.ResetBytes(in)
+	return d
+}
+
+var defaultDecNaked decNaked
+
+func newDecoder(h Handle) *Decoder {
+	d := &Decoder{h: h.getBasicHandle(), err: errDecoderNotInitialized}
+	d.hh = h
+	d.be = h.isBinary()
+	// NOTE: do not initialize d.n here. It is lazily initialized in d.naked()
+	var jh *JsonHandle
+	jh, d.js = h.(*JsonHandle)
+	if d.js {
+		d.jsms = jh.MapKeyAsString
+	}
+	d.esep = d.hh.hasElemSeparators()
+	if d.h.InternString {
+		d.is = make(map[string]string, 32)
+	}
+	d.d = h.newDecDriver(d)
+	// d.cr, _ = d.d.(containerStateRecv)
+	return d
+}
+
+func (d *Decoder) resetCommon() {
+	d.n.reset()
+	d.d.reset()
+	d.err = nil
+	// reset all things which were cached from the Handle, but could change
+	d.mtid, d.stid = 0, 0
+	d.mtr, d.str = false, false
+	if d.h.MapType != nil {
+		d.mtid = rt2id(d.h.MapType)
+		d.mtr = fastpathAV.index(d.mtid) != -1
+	}
+	if d.h.SliceType != nil {
+		d.stid = rt2id(d.h.SliceType)
+		d.str = fastpathAV.index(d.stid) != -1
+	}
+}
+
+// Reset the Decoder with a new Reader to decode from,
+// clearing all state from last run(s).
+func (d *Decoder) Reset(r io.Reader) {
+	if r == nil {
+		return
+	}
+	if d.bi == nil {
+		d.bi = new(bufioDecReader)
+	}
+	d.bytes = false
+	if d.h.ReaderBufferSize > 0 {
+		d.bi.buf = make([]byte, 0, d.h.ReaderBufferSize)
+		d.bi.reset(r)
+		d.r = d.bi
+	} else {
+		// d.ri.x = &d.b
+		// d.s = d.sa[:0]
+		if d.ri == nil {
+			d.ri = new(ioDecReader)
+		}
+		d.ri.reset(r)
+		d.r = d.ri
+	}
+	d.resetCommon()
+}
+
+// ResetBytes resets the Decoder with a new []byte to decode from,
+// clearing all state from last run(s).
+func (d *Decoder) ResetBytes(in []byte) {
+	if in == nil {
+		return
+	}
+	d.bytes = true
+	d.rb.reset(in)
+	d.r = &d.rb
+	d.resetCommon()
+}
+
+// naked must be called before each call to .DecodeNaked,
+// as they will use it.
+func (d *Decoder) naked() *decNaked {
+	if d.n == nil {
+		// consider one of:
+		//   - get from sync.Pool  (if GC is frequent, there's no value here)
+		//   - new alloc           (safest. only init'ed if it a naked decode will be done)
+		//   - field in Decoder    (makes the Decoder struct very big)
+		// To support using a decoder where a DecodeNaked is not needed,
+		// we prefer #1 or #2.
+		// d.n = new(decNaked) // &d.nv // new(decNaked) // grab from a sync.Pool
+		// d.n.init()
+		var v interface{}
+		d.nsp, v = pool.decNaked()
+		d.n = v.(*decNaked)
+	}
+	return d.n
+}
+
+// Decode decodes the stream from reader and stores the result in the
+// value pointed to by v. v cannot be a nil pointer. v can also be
+// a reflect.Value of a pointer.
+//
+// Note that a pointer to a nil interface is not a nil pointer.
+// If you do not know what type of stream it is, pass in a pointer to a nil interface.
+// We will decode and store a value in that nil interface.
+//
+// Sample usages:
+//   // Decoding into a non-nil typed value
+//   var f float32
+//   err = codec.NewDecoder(r, handle).Decode(&f)
+//
+//   // Decoding into nil interface
+//   var v interface{}
+//   dec := codec.NewDecoder(r, handle)
+//   err = dec.Decode(&v)
+//
+// When decoding into a nil interface{}, we will decode into an appropriate value based
+// on the contents of the stream:
+//   - Numbers are decoded as float64, int64 or uint64.
+//   - Other values are decoded appropriately depending on the type:
+//     bool, string, []byte, time.Time, etc
+//   - Extensions are decoded as RawExt (if no ext function registered for the tag)
+// Configurations exist on the Handle to override defaults
+// (e.g. for MapType, SliceType and how to decode raw bytes).
+//
+// When decoding into a non-nil interface{} value, the mode of encoding is based on the
+// type of the value. When a value is seen:
+//   - If an extension is registered for it, call that extension function
+//   - If it implements BinaryUnmarshaler, call its UnmarshalBinary(data []byte) error
+//   - Else decode it based on its reflect.Kind
+//
+// There are some special rules when decoding into containers (slice/array/map/struct).
+// Decode will typically use the stream contents to UPDATE the container.
+//   - A map can be decoded from a stream map, by updating matching keys.
+//   - A slice can be decoded from a stream array,
+//     by updating the first n elements, where n is length of the stream.
+//   - A slice can be decoded from a stream map, by decoding as if
+//     it contains a sequence of key-value pairs.
+//   - A struct can be decoded from a stream map, by updating matching fields.
+//   - A struct can be decoded from a stream array,
+//     by updating fields as they occur in the struct (by index).
+//
+// When decoding a stream map or array with length of 0 into a nil map or slice,
+// we reset the destination map or slice to a zero-length value.
+//
+// However, when decoding a stream nil, we reset the destination container
+// to its "zero" value (e.g. nil for slice/map, etc).
+//
+// Note: we allow nil values in the stream anywhere except for map keys.
+// A nil value in the encoded stream where a map key is expected is treated as an error.
+func (d *Decoder) Decode(v interface{}) (err error) {
+	defer d.deferred(&err)
+	d.MustDecode(v)
+	return
+}
+
+// MustDecode is like Decode, but panics if unable to Decode.
+// This provides insight to the code location that triggered the error.
+func (d *Decoder) MustDecode(v interface{}) {
+	// TODO: Top-level: ensure that v is a pointer and not nil.
+	if d.err != nil {
+		panic(d.err)
+	}
+	if d.d.TryDecodeAsNil() {
+		setZero(v)
+	} else {
+		d.decode(v)
+	}
+	d.alwaysAtEnd()
+	// xprintf(">>>>>>>> >>>>>>>> num decFns: %v\n", d.cf.sn)
+}
+
+func (d *Decoder) deferred(err1 *error) {
+	d.alwaysAtEnd()
+	if recoverPanicToErr {
+		if x := recover(); x != nil {
+			panicValToErr(d, x, err1)
+			panicValToErr(d, x, &d.err)
+		}
+	}
+}
+
+func (d *Decoder) alwaysAtEnd() {
+	if d.n != nil {
+		// if n != nil, then nsp != nil (they are always set together)
+		d.nsp.Put(d.n)
+		d.n, d.nsp = nil, nil
+	}
+	d.codecFnPooler.alwaysAtEnd()
+}
+
+// // this is not a smart swallow, as it allocates objects and does unnecessary work.
+// func (d *Decoder) swallowViaHammer() {
+// 	var blank interface{}
+// 	d.decodeValueNoFn(reflect.ValueOf(&blank).Elem())
+// }
+
+func (d *Decoder) swallow() {
+	// smarter decode that just swallows the content
+	dd := d.d
+	if dd.TryDecodeAsNil() {
+		return
+	}
+	elemsep := d.esep
+	switch dd.ContainerType() {
+	case valueTypeMap:
+		containerLen := dd.ReadMapStart()
+		hasLen := containerLen >= 0
+		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+			// if clenGtEqualZero {if j >= containerLen {break} } else if dd.CheckBreak() {break}
+			if elemsep {
+				dd.ReadMapElemKey()
+			}
+			d.swallow()
+			if elemsep {
+				dd.ReadMapElemValue()
+			}
+			d.swallow()
+		}
+		dd.ReadMapEnd()
+	case valueTypeArray:
+		containerLen := dd.ReadArrayStart()
+		hasLen := containerLen >= 0
+		for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+			if elemsep {
+				dd.ReadArrayElem()
+			}
+			d.swallow()
+		}
+		dd.ReadArrayEnd()
+	case valueTypeBytes:
+		dd.DecodeBytes(d.b[:], true)
+	case valueTypeString:
+		dd.DecodeStringAsBytes()
+	default:
+		// these are all primitives, which we can get from decodeNaked
+		// if RawExt using Value, complete the processing.
+		n := d.naked()
+		dd.DecodeNaked()
+		if n.v == valueTypeExt && n.l == nil {
+			n.initContainers()
+			if n.li < arrayCacheLen {
+				n.ia[n.li] = nil
+				n.li++
+				d.decode(&n.ia[n.li-1])
+				n.ia[n.li-1] = nil
+				n.li--
+			} else {
+				var v2 interface{}
+				d.decode(&v2)
+			}
+		}
+	}
+}
+
+func setZero(iv interface{}) {
+	if iv == nil || definitelyNil(iv) {
+		return
+	}
+	var canDecode bool
+	switch v := iv.(type) {
+	case *string:
+		*v = ""
+	case *bool:
+		*v = false
+	case *int:
+		*v = 0
+	case *int8:
+		*v = 0
+	case *int16:
+		*v = 0
+	case *int32:
+		*v = 0
+	case *int64:
+		*v = 0
+	case *uint:
+		*v = 0
+	case *uint8:
+		*v = 0
+	case *uint16:
+		*v = 0
+	case *uint32:
+		*v = 0
+	case *uint64:
+		*v = 0
+	case *float32:
+		*v = 0
+	case *float64:
+		*v = 0
+	case *[]uint8:
+		*v = nil
+	case *Raw:
+		*v = nil
+	case *time.Time:
+		*v = time.Time{}
+	case reflect.Value:
+		if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
+			v.Set(reflect.Zero(v.Type()))
+		} // TODO: else drain if chan, clear if map, set all to nil if slice???
+	default:
+		if !fastpathDecodeSetZeroTypeSwitch(iv) {
+			v := reflect.ValueOf(iv)
+			if v, canDecode = isDecodeable(v); canDecode && v.CanSet() {
+				v.Set(reflect.Zero(v.Type()))
+			} // TODO: else drain if chan, clear if map, set all to nil if slice???
+		}
+	}
+}
+
+func (d *Decoder) decode(iv interface{}) {
+	// check nil and interfaces explicitly,
+	// so that type switches just have a run of constant non-interface types.
+	if iv == nil {
+		d.errorstr(errstrCannotDecodeIntoNil)
+		return
+	}
+	if v, ok := iv.(Selfer); ok {
+		v.CodecDecodeSelf(d)
+		return
+	}
+
+	switch v := iv.(type) {
+	// case nil:
+	// case Selfer:
+
+	case reflect.Value:
+		v = d.ensureDecodeable(v)
+		d.decodeValue(v, nil, true)
+
+	case *string:
+		*v = d.d.DecodeString()
+	case *bool:
+		*v = d.d.DecodeBool()
+	case *int:
+		*v = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
+	case *int8:
+		*v = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
+	case *int16:
+		*v = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
+	case *int32:
+		*v = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
+	case *int64:
+		*v = d.d.DecodeInt64()
+	case *uint:
+		*v = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+	case *uint8:
+		*v = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
+	case *uint16:
+		*v = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
+	case *uint32:
+		*v = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
+	case *uint64:
+		*v = d.d.DecodeUint64()
+	case *float32:
+		f64 := d.d.DecodeFloat64()
+		if chkOvf.Float32(f64) {
+			d.errorf("float32 overflow: %v", f64)
+		}
+		*v = float32(f64)
+	case *float64:
+		*v = d.d.DecodeFloat64()
+	case *[]uint8:
+		*v = d.d.DecodeBytes(*v, false)
+	case []uint8:
+		b := d.d.DecodeBytes(v, false)
+		if !(len(b) > 0 && len(b) == len(v) && &b[0] == &v[0]) {
+			copy(v, b)
+		}
+	case *time.Time:
+		*v = d.d.DecodeTime()
+	case *Raw:
+		*v = d.rawBytes()
+
+	case *interface{}:
+		d.decodeValue(reflect.ValueOf(iv).Elem(), nil, true)
+		// d.decodeValueNotNil(reflect.ValueOf(iv).Elem())
+
+	default:
+		if !fastpathDecodeTypeSwitch(iv, d) {
+			v := reflect.ValueOf(iv)
+			v = d.ensureDecodeable(v)
+			d.decodeValue(v, nil, false)
+			// d.decodeValueFallback(v)
+		}
+	}
+}
+
+func (d *Decoder) decodeValue(rv reflect.Value, fn *codecFn, chkAll bool) {
+	// If stream is not containing a nil value, then we can deref to the base
+	// non-pointer value, and decode into that.
+	var rvp reflect.Value
+	var rvpValid bool
+	if rv.Kind() == reflect.Ptr {
+		rvpValid = true
+		for {
+			if rv.IsNil() {
+				rv.Set(reflect.New(rv.Type().Elem()))
+			}
+			rvp = rv
+			rv = rv.Elem()
+			if rv.Kind() != reflect.Ptr {
+				break
+			}
+		}
+	}
+
+	if fn == nil {
+		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
+		fn = d.cfer().get(rv.Type(), chkAll, true) // chkAll, chkAll)
+	}
+	if fn.i.addrD {
+		if rvpValid {
+			fn.fd(d, &fn.i, rvp)
+		} else if rv.CanAddr() {
+			fn.fd(d, &fn.i, rv.Addr())
+		} else if !fn.i.addrF {
+			fn.fd(d, &fn.i, rv)
+		} else {
+			d.errorf("cannot decode into a non-pointer value")
+		}
+	} else {
+		fn.fd(d, &fn.i, rv)
+	}
+	// return rv
+}
+
+func (d *Decoder) structFieldNotFound(index int, rvkencname string) {
+	// NOTE: rvkencname may be a stringView, so don't pass it to another function.
+	if d.h.ErrorIfNoField {
+		if index >= 0 {
+			d.errorf("no matching struct field found when decoding stream array at index %v", index)
+			return
+		} else if rvkencname != "" {
+			d.errorf("no matching struct field found when decoding stream map with key " + rvkencname)
+			return
+		}
+	}
+	d.swallow()
+}
+
+func (d *Decoder) arrayCannotExpand(sliceLen, streamLen int) {
+	if d.h.ErrorIfNoArrayExpand {
+		d.errorf("cannot expand array len during decode from %v to %v", sliceLen, streamLen)
+	}
+}
+
+func isDecodeable(rv reflect.Value) (rv2 reflect.Value, canDecode bool) {
+	switch rv.Kind() {
+	case reflect.Array:
+		return rv, true
+	case reflect.Ptr:
+		if !rv.IsNil() {
+			return rv.Elem(), true
+		}
+	case reflect.Slice, reflect.Chan, reflect.Map:
+		if !rv.IsNil() {
+			return rv, true
+		}
+	}
+	return
+}
+
+func (d *Decoder) ensureDecodeable(rv reflect.Value) (rv2 reflect.Value) {
+	// decode can take any reflect.Value that is a inherently addressable i.e.
+	//   - array
+	//   - non-nil chan    (we will SEND to it)
+	//   - non-nil slice   (we will set its elements)
+	//   - non-nil map     (we will put into it)
+	//   - non-nil pointer (we can "update" it)
+	rv2, canDecode := isDecodeable(rv)
+	if canDecode {
+		return
+	}
+	if !rv.IsValid() {
+		d.errorstr(errstrCannotDecodeIntoNil)
+		return
+	}
+	if !rv.CanInterface() {
+		d.errorf("cannot decode into a value without an interface: %v", rv)
+		return
+	}
+	rvi := rv2i(rv)
+	rvk := rv.Kind()
+	d.errorf("cannot decode into value of kind: %v, type: %T, %v", rvk, rvi, rvi)
+	return
+}
+
+// Possibly get an interned version of a string
+//
+// This should mostly be used for map keys, where the key type is string.
+// This is because keys of a map/struct are typically reused across many objects.
+func (d *Decoder) string(v []byte) (s string) {
+	if d.is == nil {
+		return string(v) // don't return stringView, as we need a real string here.
+	}
+	s, ok := d.is[string(v)] // no allocation here, per go implementation
+	if !ok {
+		s = string(v) // new allocation here
+		d.is[s] = s
+	}
+	return s
+}
+
+// nextValueBytes returns the next value in the stream as a set of bytes.
+func (d *Decoder) nextValueBytes() (bs []byte) {
+	d.d.uncacheRead()
+	d.r.track()
+	d.swallow()
+	bs = d.r.stopTrack()
+	return
+}
+
+func (d *Decoder) rawBytes() []byte {
+	// ensure that this is not a view into the bytes
+	// i.e. make new copy always.
+	bs := d.nextValueBytes()
+	bs2 := make([]byte, len(bs))
+	copy(bs2, bs)
+	return bs2
+}
+
+func (d *Decoder) wrapErrstr(v interface{}, err *error) {
+	*err = fmt.Errorf("%s decode error [pos %d]: %v", d.hh.Name(), d.r.numread(), v)
+}
+
+// --------------------------------------------------
+
+// decSliceHelper assists when decoding into a slice, from a map or an array in the stream.
+// A slice can be set from a map or array in stream. This supports the MapBySlice interface.
+type decSliceHelper struct {
+	d *Decoder
+	// ct valueType
+	array bool
+}
+
+func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) {
+	dd := d.d
+	ctyp := dd.ContainerType()
+	switch ctyp {
+	case valueTypeArray:
+		x.array = true
+		clen = dd.ReadArrayStart()
+	case valueTypeMap:
+		clen = dd.ReadMapStart() * 2
+	default:
+		d.errorf("only encoded map or array can be decoded into a slice (%d)", ctyp)
+	}
+	// x.ct = ctyp
+	x.d = d
+	return
+}
+
+func (x decSliceHelper) End() {
+	if x.array {
+		x.d.d.ReadArrayEnd()
+	} else {
+		x.d.d.ReadMapEnd()
+	}
+}
+
+func (x decSliceHelper) ElemContainerState(index int) {
+	if x.array {
+		x.d.d.ReadArrayElem()
+	} else if index%2 == 0 {
+		x.d.d.ReadMapElemKey()
+	} else {
+		x.d.d.ReadMapElemValue()
+	}
+}
+
+func decByteSlice(r decReader, clen, maxInitLen int, bs []byte) (bsOut []byte) {
+	if clen == 0 {
+		return zeroByteSlice
+	}
+	if len(bs) == clen {
+		bsOut = bs
+		r.readb(bsOut)
+	} else if cap(bs) >= clen {
+		bsOut = bs[:clen]
+		r.readb(bsOut)
+	} else {
+		// bsOut = make([]byte, clen)
+		len2 := decInferLen(clen, maxInitLen, 1)
+		bsOut = make([]byte, len2)
+		r.readb(bsOut)
+		for len2 < clen {
+			len3 := decInferLen(clen-len2, maxInitLen, 1)
+			bs3 := bsOut
+			bsOut = make([]byte, len2+len3)
+			copy(bsOut, bs3)
+			r.readb(bsOut[len2:])
+			len2 += len3
+		}
+	}
+	return
+}
+
+func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte) {
+	if xlen := len(in); xlen > 0 {
+		if isBytesReader || xlen <= scratchByteArrayLen {
+			if cap(dest) >= xlen {
+				out = dest[:xlen]
+			} else {
+				out = make([]byte, xlen)
+			}
+			copy(out, in)
+			return
+		}
+	}
+	return in
+}
+
+// decInferLen will infer a sensible length, given the following:
+//    - clen: length wanted.
+//    - maxlen: max length to be returned.
+//      if <= 0, it is unset, and we infer it based on the unit size
+//    - unit: number of bytes for each element of the collection
+func decInferLen(clen, maxlen, unit int) (rvlen int) {
+	// handle when maxlen is not set i.e. <= 0
+	if clen <= 0 {
+		return
+	}
+	if unit == 0 {
+		return clen
+	}
+	if maxlen <= 0 {
+		// no maxlen defined. Use maximum of 256K memory, with a floor of 4K items.
+		// maxlen = 256 * 1024 / unit
+		// if maxlen < (4 * 1024) {
+		// 	maxlen = 4 * 1024
+		// }
+		if unit < (256 / 4) {
+			maxlen = 256 * 1024 / unit
+		} else {
+			maxlen = 4 * 1024
+		}
+	}
+	if clen > maxlen {
+		rvlen = maxlen
+	} else {
+		rvlen = clen
+	}
+	return
+}
+
+func expandSliceRV(s reflect.Value, st reflect.Type, canChange bool, stElemSize, num, slen, scap int) (
+	s2 reflect.Value, scap2 int, changed bool, err string) {
+	l1 := slen + num // new slice length
+	if l1 < slen {
+		err = errmsgExpandSliceOverflow
+		return
+	}
+	if l1 <= scap {
+		if s.CanSet() {
+			s.SetLen(l1)
+		} else if canChange {
+			s2 = s.Slice(0, l1)
+			scap2 = scap
+			changed = true
+		} else {
+			err = errmsgExpandSliceCannotChange
+			return
+		}
+		return
+	}
+	if !canChange {
+		err = errmsgExpandSliceCannotChange
+		return
+	}
+	scap2 = growCap(scap, stElemSize, num)
+	s2 = reflect.MakeSlice(st, l1, scap2)
+	changed = true
+	reflect.Copy(s2, s)
+	return
+}
+
+func decReadFull(r io.Reader, bs []byte) (n int, err error) {
+	var nn int
+	for n < len(bs) && err == nil {
+		nn, err = r.Read(bs[n:])
+		if nn > 0 {
+			if err == io.EOF {
+				// leave EOF for next time
+				err = nil
+			}
+			n += nn
+		}
+	}
+
+	// do not do this - it serves no purpose
+	// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }
+	return
+}
diff --git a/vendor/github.com/ugorji/go/codec/encode.go b/vendor/github.com/ugorji/go/codec/encode.go
new file mode 100644
index 0000000..ef46529
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/encode.go
@@ -0,0 +1,1375 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"bufio"
+	"encoding"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+	"sort"
+	"strconv"
+	"sync"
+	"time"
+)
+
+const defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
+
+var errEncoderNotInitialized = errors.New("Encoder not initialized")
+
+// encWriter abstracts writing to a byte array or to an io.Writer.
+type encWriter interface {
+	writeb([]byte)
+	writestr(string)
+	writen1(byte)
+	writen2(byte, byte)
+	atEndOfEncode()
+}
+
+// encDriver abstracts the actual codec (binc vs msgpack, etc)
+type encDriver interface {
+	EncodeNil()
+	EncodeInt(i int64)
+	EncodeUint(i uint64)
+	EncodeBool(b bool)
+	EncodeFloat32(f float32)
+	EncodeFloat64(f float64)
+	// encodeExtPreamble(xtag byte, length int)
+	EncodeRawExt(re *RawExt, e *Encoder)
+	EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder)
+	EncodeString(c charEncoding, v string)
+	// EncodeSymbol(v string)
+	EncodeStringBytes(c charEncoding, v []byte)
+	EncodeTime(time.Time)
+	//encBignum(f *big.Int)
+	//encStringRunes(c charEncoding, v []rune)
+	WriteArrayStart(length int)
+	WriteArrayElem()
+	WriteArrayEnd()
+	WriteMapStart(length int)
+	WriteMapElemKey()
+	WriteMapElemValue()
+	WriteMapEnd()
+
+	reset()
+	atEndOfEncode()
+}
+
+type ioEncStringWriter interface {
+	WriteString(s string) (n int, err error)
+}
+
+type encDriverAsis interface {
+	EncodeAsis(v []byte)
+}
+
+type encDriverNoopContainerWriter struct{}
+
+func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
+func (encDriverNoopContainerWriter) WriteArrayElem()            {}
+func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
+func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
+func (encDriverNoopContainerWriter) WriteMapElemKey()           {}
+func (encDriverNoopContainerWriter) WriteMapElemValue()         {}
+func (encDriverNoopContainerWriter) WriteMapEnd()               {}
+func (encDriverNoopContainerWriter) atEndOfEncode()             {}
+
+type encDriverTrackContainerWriter struct {
+	c containerState
+}
+
+func (e *encDriverTrackContainerWriter) WriteArrayStart(length int) { e.c = containerArrayStart }
+func (e *encDriverTrackContainerWriter) WriteArrayElem()            { e.c = containerArrayElem }
+func (e *encDriverTrackContainerWriter) WriteArrayEnd()             { e.c = containerArrayEnd }
+func (e *encDriverTrackContainerWriter) WriteMapStart(length int)   { e.c = containerMapStart }
+func (e *encDriverTrackContainerWriter) WriteMapElemKey()           { e.c = containerMapKey }
+func (e *encDriverTrackContainerWriter) WriteMapElemValue()         { e.c = containerMapValue }
+func (e *encDriverTrackContainerWriter) WriteMapEnd()               { e.c = containerMapEnd }
+func (e *encDriverTrackContainerWriter) atEndOfEncode()             {}
+
+// type ioEncWriterWriter interface {
+// 	WriteByte(c byte) error
+// 	WriteString(s string) (n int, err error)
+// 	Write(p []byte) (n int, err error)
+// }
+
+// EncodeOptions captures configuration options during encode.
+type EncodeOptions struct {
+	// WriterBufferSize is the size of the buffer used when writing.
+	//
+	// if > 0, we use a smart buffer internally for performance purposes.
+	WriterBufferSize int
+
+	// ChanRecvTimeout is the timeout used when selecting from a chan.
+	//
+	// Configuring this controls how we receive from a chan during the encoding process.
+	//   - If ==0, we only consume the elements currently available in the chan.
+	//   - if  <0, we consume until the chan is closed.
+	//   - If  >0, we consume until this timeout.
+	ChanRecvTimeout time.Duration
+
+	// StructToArray specifies to encode a struct as an array, and not as a map
+	StructToArray bool
+
+	// Canonical representation means that encoding a value will always result in the same
+	// sequence of bytes.
+	//
+	// This only affects maps, as the iteration order for maps is random.
+	//
+	// The implementation MAY use the natural sort order for the map keys if possible:
+	//
+	//     - If there is a natural sort order (ie for number, bool, string or []byte keys),
+	//       then the map keys are first sorted in natural order and then written
+	//       with corresponding map values to the strema.
+	//     - If there is no natural sort order, then the map keys will first be
+	//       encoded into []byte, and then sorted,
+	//       before writing the sorted keys and the corresponding map values to the stream.
+	//
+	Canonical bool
+
+	// CheckCircularRef controls whether we check for circular references
+	// and error fast during an encode.
+	//
+	// If enabled, an error is received if a pointer to a struct
+	// references itself either directly or through one of its fields (iteratively).
+	//
+	// This is opt-in, as there may be a performance hit to checking circular references.
+	CheckCircularRef bool
+
+	// RecursiveEmptyCheck controls whether we descend into interfaces, structs and pointers
+	// when checking if a value is empty.
+	//
+	// Note that this may make OmitEmpty more expensive, as it incurs a lot more reflect calls.
+	RecursiveEmptyCheck bool
+
+	// Raw controls whether we encode Raw values.
+	// This is a "dangerous" option and must be explicitly set.
+	// If set, we blindly encode Raw values as-is, without checking
+	// if they are a correct representation of a value in that format.
+	// If unset, we error out.
+	Raw bool
+
+	// // AsSymbols defines what should be encoded as symbols.
+	// //
+	// // Encoding as symbols can reduce the encoded size significantly.
+	// //
+	// // However, during decoding, each string to be encoded as a symbol must
+	// // be checked to see if it has been seen before. Consequently, encoding time
+	// // will increase if using symbols, because string comparisons has a clear cost.
+	// //
+	// // Sample values:
+	// //   AsSymbolNone
+	// //   AsSymbolAll
+	// //   AsSymbolMapStringKeys
+	// //   AsSymbolMapStringKeysFlag | AsSymbolStructFieldNameFlag
+	// AsSymbols AsSymbolFlag
+}
+
+// ---------------------------------------------
+
+// ioEncWriter implements encWriter and can write to an io.Writer implementation
+type ioEncWriter struct {
+	w  io.Writer
+	ww io.Writer
+	bw io.ByteWriter
+	sw ioEncStringWriter
+	fw ioFlusher
+	b  [8]byte
+}
+
+func (z *ioEncWriter) WriteByte(b byte) (err error) {
+	z.b[0] = b
+	_, err = z.w.Write(z.b[:1])
+	return
+}
+
+func (z *ioEncWriter) WriteString(s string) (n int, err error) {
+	return z.w.Write(bytesView(s))
+}
+
+func (z *ioEncWriter) writeb(bs []byte) {
+	if _, err := z.ww.Write(bs); err != nil {
+		panic(err)
+	}
+}
+
+func (z *ioEncWriter) writestr(s string) {
+	if _, err := z.sw.WriteString(s); err != nil {
+		panic(err)
+	}
+}
+
+func (z *ioEncWriter) writen1(b byte) {
+	if err := z.bw.WriteByte(b); err != nil {
+		panic(err)
+	}
+}
+
+func (z *ioEncWriter) writen2(b1, b2 byte) {
+	var err error
+	if err = z.bw.WriteByte(b1); err == nil {
+		if err = z.bw.WriteByte(b2); err == nil {
+			return
+		}
+	}
+	panic(err)
+}
+
+// func (z *ioEncWriter) writen5(b1, b2, b3, b4, b5 byte) {
+// 	z.b[0], z.b[1], z.b[2], z.b[3], z.b[4] = b1, b2, b3, b4, b5
+// 	if _, err := z.ww.Write(z.b[:5]); err != nil {
+// 		panic(err)
+// 	}
+// }
+
+func (z *ioEncWriter) atEndOfEncode() {
+	if z.fw != nil {
+		if err := z.fw.Flush(); err != nil {
+			panic(err)
+		}
+	}
+}
+
+// ---------------------------------------------
+
+// bytesEncAppender implements encWriter and can write to an byte slice.
+type bytesEncAppender struct {
+	b   []byte
+	out *[]byte
+}
+
+func (z *bytesEncAppender) writeb(s []byte) {
+	z.b = append(z.b, s...)
+}
+func (z *bytesEncAppender) writestr(s string) {
+	z.b = append(z.b, s...)
+}
+func (z *bytesEncAppender) writen1(b1 byte) {
+	z.b = append(z.b, b1)
+}
+func (z *bytesEncAppender) writen2(b1, b2 byte) {
+	z.b = append(z.b, b1, b2)
+}
+func (z *bytesEncAppender) atEndOfEncode() {
+	*(z.out) = z.b
+}
+func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
+	z.b = in[:0]
+	z.out = out
+}
+
+// ---------------------------------------------
+
+func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeRawExt(rv2i(rv).(*RawExt), e)
+}
+
+func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn, e)
+}
+
+func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
+	rv2i(rv).(Selfer).CodecEncodeSelf(e)
+}
+
+func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
+	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
+	e.marshal(bs, fnerr, false, cRAW)
+}
+
+func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
+	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
+	e.marshal(bs, fnerr, false, cUTF8)
+}
+
+func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
+	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
+	e.marshal(bs, fnerr, true, cUTF8)
+}
+
+func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
+	e.rawBytes(rv2i(rv).(Raw))
+}
+
+func (e *Encoder) kInvalid(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeNil()
+}
+
+func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
+	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
+}
+
+func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
+	ti := f.ti
+	ee := e.e
+	// array may be non-addressable, so we have to manage with care
+	//   (don't call rv.Bytes, rv.Slice, etc).
+	// E.g. type struct S{B [2]byte};
+	//   Encode(S{}) will bomb on "panic: slice of unaddressable array".
+	if f.seq != seqTypeArray {
+		if rv.IsNil() {
+			ee.EncodeNil()
+			return
+		}
+		// If in this method, then there was no extension function defined.
+		// So it's okay to treat as []byte.
+		if ti.rtid == uint8SliceTypId {
+			ee.EncodeStringBytes(cRAW, rv.Bytes())
+			return
+		}
+	}
+	if f.seq == seqTypeChan && ti.chandir&uint8(reflect.RecvDir) == 0 {
+		e.errorf("send-only channel cannot be encoded")
+	}
+	elemsep := e.esep
+	rtelem := ti.elem
+	rtelemIsByte := uint8TypId == rt2id(rtelem) // NOT rtelem.Kind() == reflect.Uint8
+	var l int
+	// if a slice, array or chan of bytes, treat specially
+	if rtelemIsByte {
+		switch f.seq {
+		case seqTypeSlice:
+			ee.EncodeStringBytes(cRAW, rv.Bytes())
+		case seqTypeArray:
+			l = rv.Len()
+			if rv.CanAddr() {
+				ee.EncodeStringBytes(cRAW, rv.Slice(0, l).Bytes())
+			} else {
+				var bs []byte
+				if l <= cap(e.b) {
+					bs = e.b[:l]
+				} else {
+					bs = make([]byte, l)
+				}
+				reflect.Copy(reflect.ValueOf(bs), rv)
+				ee.EncodeStringBytes(cRAW, bs)
+			}
+		case seqTypeChan:
+			// do not use range, so that the number of elements encoded
+			// does not change, and encoding does not hang waiting on someone to close chan.
+			// for b := range rv2i(rv).(<-chan byte) { bs = append(bs, b) }
+			// ch := rv2i(rv).(<-chan byte) // fix error - that this is a chan byte, not a <-chan byte.
+
+			if rv.IsNil() {
+				ee.EncodeNil()
+				break
+			}
+			bs := e.b[:0]
+			irv := rv2i(rv)
+			ch, ok := irv.(<-chan byte)
+			if !ok {
+				ch = irv.(chan byte)
+			}
+
+		L1:
+			switch timeout := e.h.ChanRecvTimeout; {
+			case timeout == 0: // only consume available
+				for {
+					select {
+					case b := <-ch:
+						bs = append(bs, b)
+					default:
+						break L1
+					}
+				}
+			case timeout > 0: // consume until timeout
+				tt := time.NewTimer(timeout)
+				for {
+					select {
+					case b := <-ch:
+						bs = append(bs, b)
+					case <-tt.C:
+						// close(tt.C)
+						break L1
+					}
+				}
+			default: // consume until close
+				for b := range ch {
+					bs = append(bs, b)
+				}
+			}
+
+			ee.EncodeStringBytes(cRAW, bs)
+		}
+		return
+	}
+
+	// if chan, consume chan into a slice, and work off that slice.
+	var rvcs reflect.Value
+	if f.seq == seqTypeChan {
+		rvcs = reflect.Zero(reflect.SliceOf(rtelem))
+		timeout := e.h.ChanRecvTimeout
+		if timeout < 0 { // consume until close
+			for {
+				recv, recvOk := rv.Recv()
+				if !recvOk {
+					break
+				}
+				rvcs = reflect.Append(rvcs, recv)
+			}
+		} else {
+			cases := make([]reflect.SelectCase, 2)
+			cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
+			if timeout == 0 {
+				cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
+			} else {
+				tt := time.NewTimer(timeout)
+				cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tt.C)}
+			}
+			for {
+				chosen, recv, recvOk := reflect.Select(cases)
+				if chosen == 1 || !recvOk {
+					break
+				}
+				rvcs = reflect.Append(rvcs, recv)
+			}
+		}
+		rv = rvcs // TODO: ensure this doesn't mess up anywhere that rv of kind chan is expected
+	}
+
+	l = rv.Len()
+	if ti.mbs {
+		if l%2 == 1 {
+			e.errorf("mapBySlice requires even slice length, but got %v", l)
+			return
+		}
+		ee.WriteMapStart(l / 2)
+	} else {
+		ee.WriteArrayStart(l)
+	}
+
+	if l > 0 {
+		var fn *codecFn
+		for rtelem.Kind() == reflect.Ptr {
+			rtelem = rtelem.Elem()
+		}
+		// if kind is reflect.Interface, do not pre-determine the
+		// encoding type, because preEncodeValue may break it down to
+		// a concrete type and kInterface will bomb.
+		if rtelem.Kind() != reflect.Interface {
+			fn = e.cfer().get(rtelem, true, true)
+		}
+		for j := 0; j < l; j++ {
+			if elemsep {
+				if ti.mbs {
+					if j%2 == 0 {
+						ee.WriteMapElemKey()
+					} else {
+						ee.WriteMapElemValue()
+					}
+				} else {
+					ee.WriteArrayElem()
+				}
+			}
+			e.encodeValue(rv.Index(j), fn, true)
+		}
+	}
+
+	if ti.mbs {
+		ee.WriteMapEnd()
+	} else {
+		ee.WriteArrayEnd()
+	}
+}
+
+func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
+	fti := f.ti
+	elemsep := e.esep
+	tisfi := fti.sfiSrc
+	toMap := !(fti.toArray || e.h.StructToArray)
+	if toMap {
+		tisfi = fti.sfiSort
+	}
+	ee := e.e
+
+	sfn := structFieldNode{v: rv, update: false}
+	if toMap {
+		ee.WriteMapStart(len(tisfi))
+		if elemsep {
+			for _, si := range tisfi {
+				ee.WriteMapElemKey()
+				// ee.EncodeString(cUTF8, si.encName)
+				encStructFieldKey(ee, fti.keyType, si.encName)
+				ee.WriteMapElemValue()
+				e.encodeValue(sfn.field(si), nil, true)
+			}
+		} else {
+			for _, si := range tisfi {
+				// ee.EncodeString(cUTF8, si.encName)
+				encStructFieldKey(ee, fti.keyType, si.encName)
+				e.encodeValue(sfn.field(si), nil, true)
+			}
+		}
+		ee.WriteMapEnd()
+	} else {
+		ee.WriteArrayStart(len(tisfi))
+		if elemsep {
+			for _, si := range tisfi {
+				ee.WriteArrayElem()
+				e.encodeValue(sfn.field(si), nil, true)
+			}
+		} else {
+			for _, si := range tisfi {
+				e.encodeValue(sfn.field(si), nil, true)
+			}
+		}
+		ee.WriteArrayEnd()
+	}
+}
+
+func encStructFieldKey(ee encDriver, keyType valueType, s string) {
+	var m must
+
+	// use if-else-if, not switch (which compiles to binary-search)
+	// since keyType is typically valueTypeString, branch prediction is pretty good.
+
+	if keyType == valueTypeString {
+		ee.EncodeString(cUTF8, s)
+	} else if keyType == valueTypeInt {
+		ee.EncodeInt(m.Int(strconv.ParseInt(s, 10, 64)))
+	} else if keyType == valueTypeUint {
+		ee.EncodeUint(m.Uint(strconv.ParseUint(s, 10, 64)))
+	} else if keyType == valueTypeFloat {
+		ee.EncodeFloat64(m.Float(strconv.ParseFloat(s, 64)))
+	} else {
+		ee.EncodeString(cUTF8, s)
+	}
+}
+
+func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
+	fti := f.ti
+	elemsep := e.esep
+	tisfi := fti.sfiSrc
+	toMap := !(fti.toArray || e.h.StructToArray)
+	// if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct)
+	if toMap {
+		tisfi = fti.sfiSort
+	}
+	newlen := len(fti.sfiSort)
+	ee := e.e
+
+	// Use sync.Pool to reduce allocating slices unnecessarily.
+	// The cost of sync.Pool is less than the cost of new allocation.
+	//
+	// Each element of the array pools one of encStructPool(8|16|32|64).
+	// It allows the re-use of slices up to 64 in length.
+	// A performance cost of encoding structs was collecting
+	// which values were empty and should be omitted.
+	// We needed slices of reflect.Value and string to collect them.
+	// This shared pool reduces the amount of unnecessary creation we do.
+	// The cost is that of locking sometimes, but sync.Pool is efficient
+	// enough to reduce thread contention.
+
+	var spool *sync.Pool
+	var poolv interface{}
+	var fkvs []stringRv
+	// fmt.Printf(">>>>>>>>>>>>>> encode.kStruct: newlen: %d\n", newlen)
+	if newlen <= 8 {
+		spool, poolv = pool.stringRv8()
+		fkvs = poolv.(*[8]stringRv)[:newlen]
+	} else if newlen <= 16 {
+		spool, poolv = pool.stringRv16()
+		fkvs = poolv.(*[16]stringRv)[:newlen]
+	} else if newlen <= 32 {
+		spool, poolv = pool.stringRv32()
+		fkvs = poolv.(*[32]stringRv)[:newlen]
+	} else if newlen <= 64 {
+		spool, poolv = pool.stringRv64()
+		fkvs = poolv.(*[64]stringRv)[:newlen]
+	} else if newlen <= 128 {
+		spool, poolv = pool.stringRv128()
+		fkvs = poolv.(*[128]stringRv)[:newlen]
+	} else {
+		fkvs = make([]stringRv, newlen)
+	}
+
+	newlen = 0
+	var kv stringRv
+	recur := e.h.RecursiveEmptyCheck
+	sfn := structFieldNode{v: rv, update: false}
+	for _, si := range tisfi {
+		// kv.r = si.field(rv, false)
+		kv.r = sfn.field(si)
+		if toMap {
+			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
+				continue
+			}
+			kv.v = si.encName
+		} else {
+			// use the zero value.
+			// if a reference or struct, set to nil (so you do not output too much)
+			if si.omitEmpty() && isEmptyValue(kv.r, e.h.TypeInfos, recur, recur) {
+				switch kv.r.Kind() {
+				case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
+					kv.r = reflect.Value{} //encode as nil
+				}
+			}
+		}
+		fkvs[newlen] = kv
+		newlen++
+	}
+
+	if toMap {
+		ee.WriteMapStart(newlen)
+		if elemsep {
+			for j := 0; j < newlen; j++ {
+				kv = fkvs[j]
+				ee.WriteMapElemKey()
+				// ee.EncodeString(cUTF8, kv.v)
+				encStructFieldKey(ee, fti.keyType, kv.v)
+				ee.WriteMapElemValue()
+				e.encodeValue(kv.r, nil, true)
+			}
+		} else {
+			for j := 0; j < newlen; j++ {
+				kv = fkvs[j]
+				// ee.EncodeString(cUTF8, kv.v)
+				encStructFieldKey(ee, fti.keyType, kv.v)
+				e.encodeValue(kv.r, nil, true)
+			}
+		}
+		ee.WriteMapEnd()
+	} else {
+		ee.WriteArrayStart(newlen)
+		if elemsep {
+			for j := 0; j < newlen; j++ {
+				ee.WriteArrayElem()
+				e.encodeValue(fkvs[j].r, nil, true)
+			}
+		} else {
+			for j := 0; j < newlen; j++ {
+				e.encodeValue(fkvs[j].r, nil, true)
+			}
+		}
+		ee.WriteArrayEnd()
+	}
+
+	// do not use defer. Instead, use explicit pool return at end of function.
+	// defer has a cost we are trying to avoid.
+	// If there is a panic and these slices are not returned, it is ok.
+	if spool != nil {
+		spool.Put(poolv)
+	}
+}
+
+func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
+	ee := e.e
+	if rv.IsNil() {
+		ee.EncodeNil()
+		return
+	}
+
+	l := rv.Len()
+	ee.WriteMapStart(l)
+	elemsep := e.esep
+	if l == 0 {
+		ee.WriteMapEnd()
+		return
+	}
+	// var asSymbols bool
+	// determine the underlying key and val encFn's for the map.
+	// This eliminates some work which is done for each loop iteration i.e.
+	// rv.Type(), ref.ValueOf(rt).Pointer(), then check map/list for fn.
+	//
+	// However, if kind is reflect.Interface, do not pre-determine the
+	// encoding type, because preEncodeValue may break it down to
+	// a concrete type and kInterface will bomb.
+	var keyFn, valFn *codecFn
+	ti := f.ti
+	rtkey0 := ti.key
+	rtkey := rtkey0
+	rtval0 := ti.elem
+	rtval := rtval0
+	// rtkeyid := rt2id(rtkey0)
+	for rtval.Kind() == reflect.Ptr {
+		rtval = rtval.Elem()
+	}
+	if rtval.Kind() != reflect.Interface {
+		valFn = e.cfer().get(rtval, true, true)
+	}
+	mks := rv.MapKeys()
+
+	if e.h.Canonical {
+		e.kMapCanonical(rtkey, rv, mks, valFn)
+		ee.WriteMapEnd()
+		return
+	}
+
+	var keyTypeIsString = stringTypId == rt2id(rtkey0) // rtkeyid
+	if !keyTypeIsString {
+		for rtkey.Kind() == reflect.Ptr {
+			rtkey = rtkey.Elem()
+		}
+		if rtkey.Kind() != reflect.Interface {
+			// rtkeyid = rt2id(rtkey)
+			keyFn = e.cfer().get(rtkey, true, true)
+		}
+	}
+
+	// for j, lmks := 0, len(mks); j < lmks; j++ {
+	for j := range mks {
+		if elemsep {
+			ee.WriteMapElemKey()
+		}
+		if keyTypeIsString {
+			ee.EncodeString(cUTF8, mks[j].String())
+		} else {
+			e.encodeValue(mks[j], keyFn, true)
+		}
+		if elemsep {
+			ee.WriteMapElemValue()
+		}
+		e.encodeValue(rv.MapIndex(mks[j]), valFn, true)
+
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) kMapCanonical(rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *codecFn) {
+	ee := e.e
+	elemsep := e.esep
+	// we previously did out-of-band if an extension was registered.
+	// This is not necessary, as the natural kind is sufficient for ordering.
+
+	switch rtkey.Kind() {
+	case reflect.Bool:
+		mksv := make([]boolRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.Bool()
+		}
+		sort.Sort(boolRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeBool(mksv[i].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.String:
+		mksv := make([]stringRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.String()
+		}
+		sort.Sort(stringRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeString(cUTF8, mksv[i].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
+		mksv := make([]uintRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.Uint()
+		}
+		sort.Sort(uintRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeUint(mksv[i].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+		mksv := make([]intRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.Int()
+		}
+		sort.Sort(intRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeInt(mksv[i].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.Float32:
+		mksv := make([]floatRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.Float()
+		}
+		sort.Sort(floatRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeFloat32(float32(mksv[i].v))
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.Float64:
+		mksv := make([]floatRv, len(mks))
+		for i, k := range mks {
+			v := &mksv[i]
+			v.r = k
+			v.v = k.Float()
+		}
+		sort.Sort(floatRvSlice(mksv))
+		for i := range mksv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			ee.EncodeFloat64(mksv[i].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+		}
+	case reflect.Struct:
+		if rv.Type() == timeTyp {
+			mksv := make([]timeRv, len(mks))
+			for i, k := range mks {
+				v := &mksv[i]
+				v.r = k
+				v.v = rv2i(k).(time.Time)
+			}
+			sort.Sort(timeRvSlice(mksv))
+			for i := range mksv {
+				if elemsep {
+					ee.WriteMapElemKey()
+				}
+				ee.EncodeTime(mksv[i].v)
+				if elemsep {
+					ee.WriteMapElemValue()
+				}
+				e.encodeValue(rv.MapIndex(mksv[i].r), valFn, true)
+			}
+			break
+		}
+		fallthrough
+	default:
+		// out-of-band
+		// first encode each key to a []byte first, then sort them, then record
+		var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		mksbv := make([]bytesRv, len(mks))
+		for i, k := range mks {
+			v := &mksbv[i]
+			l := len(mksv)
+			e2.MustEncode(k)
+			v.r = k
+			v.v = mksv[l:]
+		}
+		sort.Sort(bytesRvSlice(mksbv))
+		for j := range mksbv {
+			if elemsep {
+				ee.WriteMapElemKey()
+			}
+			e.asis(mksbv[j].v)
+			if elemsep {
+				ee.WriteMapElemValue()
+			}
+			e.encodeValue(rv.MapIndex(mksbv[j].r), valFn, true)
+		}
+	}
+}
+
+// // --------------------------------------------------
+
+type encWriterSwitch struct {
+	wi *ioEncWriter
+	// wb bytesEncWriter
+	wb   bytesEncAppender
+	wx   bool // if bytes, wx=true
+	esep bool // whether it has elem separators
+	isas bool // whether e.as != nil
+}
+
+// // TODO: Uncomment after mid-stack inlining enabled in go 1.11
+
+// func (z *encWriterSwitch) writeb(s []byte) {
+// 	if z.wx {
+// 		z.wb.writeb(s)
+// 	} else {
+// 		z.wi.writeb(s)
+// 	}
+// }
+// func (z *encWriterSwitch) writestr(s string) {
+// 	if z.wx {
+// 		z.wb.writestr(s)
+// 	} else {
+// 		z.wi.writestr(s)
+// 	}
+// }
+// func (z *encWriterSwitch) writen1(b1 byte) {
+// 	if z.wx {
+// 		z.wb.writen1(b1)
+// 	} else {
+// 		z.wi.writen1(b1)
+// 	}
+// }
+// func (z *encWriterSwitch) writen2(b1, b2 byte) {
+// 	if z.wx {
+// 		z.wb.writen2(b1, b2)
+// 	} else {
+// 		z.wi.writen2(b1, b2)
+// 	}
+// }
+
+// An Encoder writes an object to an output stream in the codec format.
+type Encoder struct {
+	panicHdl
+	// hopefully, reduce derefencing cost by laying the encWriter inside the Encoder
+	e encDriver
+	// NOTE: Encoder shouldn't call it's write methods,
+	// as the handler MAY need to do some coordination.
+	w encWriter
+
+	h  *BasicHandle
+	bw *bufio.Writer
+	as encDriverAsis
+
+	// ---- cpu cache line boundary?
+
+	// ---- cpu cache line boundary?
+	encWriterSwitch
+	err error
+
+	// ---- cpu cache line boundary?
+	codecFnPooler
+	ci set
+	js bool    // here, so that no need to piggy back on *codecFner for this
+	be bool    // here, so that no need to piggy back on *codecFner for this
+	_  [6]byte // padding
+
+	// ---- writable fields during execution --- *try* to keep in sep cache line
+
+	// ---- cpu cache line boundary?
+	// b [scratchByteArrayLen]byte
+	// _ [cacheLineSize - scratchByteArrayLen]byte // padding
+	b [cacheLineSize - 0]byte // used for encoding a chan or (non-addressable) array of bytes
+}
+
+// NewEncoder returns an Encoder for encoding into an io.Writer.
+//
+// For efficiency, Users are encouraged to pass in a memory buffered writer
+// (eg bufio.Writer, bytes.Buffer).
+func NewEncoder(w io.Writer, h Handle) *Encoder {
+	e := newEncoder(h)
+	e.Reset(w)
+	return e
+}
+
+// NewEncoderBytes returns an encoder for encoding directly and efficiently
+// into a byte slice, using zero-copying to temporary slices.
+//
+// It will potentially replace the output byte slice pointed to.
+// After encoding, the out parameter contains the encoded contents.
+func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
+	e := newEncoder(h)
+	e.ResetBytes(out)
+	return e
+}
+
+func newEncoder(h Handle) *Encoder {
+	e := &Encoder{h: h.getBasicHandle(), err: errEncoderNotInitialized}
+	e.hh = h
+	e.esep = h.hasElemSeparators()
+	return e
+}
+
+func (e *Encoder) resetCommon() {
+	if e.e == nil || e.hh.recreateEncDriver(e.e) {
+		e.e = e.hh.newEncDriver(e)
+		e.as, e.isas = e.e.(encDriverAsis)
+		// e.cr, _ = e.e.(containerStateRecv)
+	}
+	e.be = e.hh.isBinary()
+	_, e.js = e.hh.(*JsonHandle)
+	e.e.reset()
+	e.err = nil
+}
+
+// Reset resets the Encoder with a new output stream.
+//
+// This accommodates using the state of the Encoder,
+// where it has "cached" information about sub-engines.
+func (e *Encoder) Reset(w io.Writer) {
+	if w == nil {
+		return
+	}
+	if e.wi == nil {
+		e.wi = new(ioEncWriter)
+	}
+	var ok bool
+	e.wx = false
+	e.wi.w = w
+	if e.h.WriterBufferSize > 0 {
+		e.bw = bufio.NewWriterSize(w, e.h.WriterBufferSize)
+		e.wi.bw = e.bw
+		e.wi.sw = e.bw
+		e.wi.fw = e.bw
+		e.wi.ww = e.bw
+	} else {
+		if e.wi.bw, ok = w.(io.ByteWriter); !ok {
+			e.wi.bw = e.wi
+		}
+		if e.wi.sw, ok = w.(ioEncStringWriter); !ok {
+			e.wi.sw = e.wi
+		}
+		e.wi.fw, _ = w.(ioFlusher)
+		e.wi.ww = w
+	}
+	e.w = e.wi
+	e.resetCommon()
+}
+
+// ResetBytes resets the Encoder with a new destination output []byte.
+func (e *Encoder) ResetBytes(out *[]byte) {
+	if out == nil {
+		return
+	}
+	var in []byte
+	if out != nil {
+		in = *out
+	}
+	if in == nil {
+		in = make([]byte, defEncByteBufSize)
+	}
+	e.wx = true
+	e.wb.reset(in, out)
+	e.w = &e.wb
+	e.resetCommon()
+}
+
+// Encode writes an object into a stream.
+//
+// Encoding can be configured via the struct tag for the fields.
+// The key (in the struct tags) that we look at is configurable.
+//
+// By default, we look up the "codec" key in the struct field's tags,
+// and fall bak to the "json" key if "codec" is absent.
+// That key in struct field's tag value is the key name,
+// followed by an optional comma and options.
+//
+// To set an option on all fields (e.g. omitempty on all fields), you
+// can create a field called _struct, and set flags on it. The options
+// which can be set on _struct are:
+//    - omitempty: so all fields are omitted if empty
+//    - toarray: so struct is encoded as an array
+//    - int: so struct key names are encoded as signed integers (instead of strings)
+//    - uint: so struct key names are encoded as unsigned integers (instead of strings)
+//    - float: so struct key names are encoded as floats (instead of strings)
+// More details on these below.
+//
+// Struct values "usually" encode as maps. Each exported struct field is encoded unless:
+//    - the field's tag is "-", OR
+//    - the field is empty (empty or the zero value) and its tag specifies the "omitempty" option.
+//
+// When encoding as a map, the first string in the tag (before the comma)
+// is the map key string to use when encoding.
+// ...
+// This key is typically encoded as a string.
+// However, there are instances where the encoded stream has mapping keys encoded as numbers.
+// For example, some cbor streams have keys as integer codes in the stream, but they should map
+// to fields in a structured object. Consequently, a struct is the natural representation in code.
+// For these, configure the struct to encode/decode the keys as numbers (instead of string).
+// This is done with the int,uint or float option on the _struct field (see above).
+//
+// However, struct values may encode as arrays. This happens when:
+//    - StructToArray Encode option is set, OR
+//    - the tag on the _struct field sets the "toarray" option
+// Note that omitempty is ignored when encoding struct values as arrays,
+// as an entry must be encoded for each field, to maintain its position.
+//
+// Values with types that implement MapBySlice are encoded as stream maps.
+//
+// The empty values (for omitempty option) are false, 0, any nil pointer
+// or interface value, and any array, slice, map, or string of length zero.
+//
+// Anonymous fields are encoded inline except:
+//    - the struct tag specifies a replacement name (first value)
+//    - the field is of an interface type
+//
+// Examples:
+//
+//      // NOTE: 'json:' can be used as struct tag key, in place 'codec:' below.
+//      type MyStruct struct {
+//          _struct bool    `codec:",omitempty"`   //set omitempty for every field
+//          Field1 string   `codec:"-"`            //skip this field
+//          Field2 int      `codec:"myName"`       //Use key "myName" in encode stream
+//          Field3 int32    `codec:",omitempty"`   //use key "Field3". Omit if empty.
+//          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
+//          io.Reader                              //use key "Reader".
+//          MyStruct        `codec:"my1"           //use key "my1".
+//          MyStruct                               //inline it
+//          ...
+//      }
+//
+//      type MyStruct struct {
+//          _struct bool    `codec:",toarray"`     //encode struct as an array
+//      }
+//
+//      type MyStruct struct {
+//          _struct bool    `codec:",uint"`        //encode struct with "unsigned integer" keys
+//          Field1 string   `codec:"1"`            //encode Field1 key using: EncodeInt(1)
+//          Field2 string   `codec:"2"`            //encode Field2 key using: EncodeInt(2)
+//      }
+//
+// The mode of encoding is based on the type of the value. When a value is seen:
+//   - If a Selfer, call its CodecEncodeSelf method
+//   - If an extension is registered for it, call that extension function
+//   - If implements encoding.(Binary|Text|JSON)Marshaler, call Marshal(Binary|Text|JSON) method
+//   - Else encode it based on its reflect.Kind
+//
+// Note that struct field names and keys in map[string]XXX will be treated as symbols.
+// Some formats support symbols (e.g. binc) and will properly encode the string
+// only once in the stream, and use a tag to refer to it thereafter.
+func (e *Encoder) Encode(v interface{}) (err error) {
+	defer e.deferred(&err)
+	e.MustEncode(v)
+	return
+}
+
+// MustEncode is like Encode, but panics if unable to Encode.
+// This provides insight to the code location that triggered the error.
+func (e *Encoder) MustEncode(v interface{}) {
+	if e.err != nil {
+		panic(e.err)
+	}
+	e.encode(v)
+	e.e.atEndOfEncode()
+	e.w.atEndOfEncode()
+	e.alwaysAtEnd()
+}
+
+func (e *Encoder) deferred(err1 *error) {
+	e.alwaysAtEnd()
+	if recoverPanicToErr {
+		if x := recover(); x != nil {
+			panicValToErr(e, x, err1)
+			panicValToErr(e, x, &e.err)
+		}
+	}
+}
+
+// func (e *Encoder) alwaysAtEnd() {
+// 	e.codecFnPooler.alwaysAtEnd()
+// }
+
+func (e *Encoder) encode(iv interface{}) {
+	if iv == nil || definitelyNil(iv) {
+		e.e.EncodeNil()
+		return
+	}
+	if v, ok := iv.(Selfer); ok {
+		v.CodecEncodeSelf(e)
+		return
+	}
+
+	// a switch with only concrete types can be optimized.
+	// consequently, we deal with nil and interfaces outside.
+
+	switch v := iv.(type) {
+	case Raw:
+		e.rawBytes(v)
+	case reflect.Value:
+		e.encodeValue(v, nil, true)
+
+	case string:
+		e.e.EncodeString(cUTF8, v)
+	case bool:
+		e.e.EncodeBool(v)
+	case int:
+		e.e.EncodeInt(int64(v))
+	case int8:
+		e.e.EncodeInt(int64(v))
+	case int16:
+		e.e.EncodeInt(int64(v))
+	case int32:
+		e.e.EncodeInt(int64(v))
+	case int64:
+		e.e.EncodeInt(v)
+	case uint:
+		e.e.EncodeUint(uint64(v))
+	case uint8:
+		e.e.EncodeUint(uint64(v))
+	case uint16:
+		e.e.EncodeUint(uint64(v))
+	case uint32:
+		e.e.EncodeUint(uint64(v))
+	case uint64:
+		e.e.EncodeUint(v)
+	case uintptr:
+		e.e.EncodeUint(uint64(v))
+	case float32:
+		e.e.EncodeFloat32(v)
+	case float64:
+		e.e.EncodeFloat64(v)
+	case time.Time:
+		e.e.EncodeTime(v)
+	case []uint8:
+		e.e.EncodeStringBytes(cRAW, v)
+
+	case *Raw:
+		e.rawBytes(*v)
+
+	case *string:
+		e.e.EncodeString(cUTF8, *v)
+	case *bool:
+		e.e.EncodeBool(*v)
+	case *int:
+		e.e.EncodeInt(int64(*v))
+	case *int8:
+		e.e.EncodeInt(int64(*v))
+	case *int16:
+		e.e.EncodeInt(int64(*v))
+	case *int32:
+		e.e.EncodeInt(int64(*v))
+	case *int64:
+		e.e.EncodeInt(*v)
+	case *uint:
+		e.e.EncodeUint(uint64(*v))
+	case *uint8:
+		e.e.EncodeUint(uint64(*v))
+	case *uint16:
+		e.e.EncodeUint(uint64(*v))
+	case *uint32:
+		e.e.EncodeUint(uint64(*v))
+	case *uint64:
+		e.e.EncodeUint(*v)
+	case *uintptr:
+		e.e.EncodeUint(uint64(*v))
+	case *float32:
+		e.e.EncodeFloat32(*v)
+	case *float64:
+		e.e.EncodeFloat64(*v)
+	case *time.Time:
+		e.e.EncodeTime(*v)
+
+	case *[]uint8:
+		e.e.EncodeStringBytes(cRAW, *v)
+
+	default:
+		if !fastpathEncodeTypeSwitch(iv, e) {
+			// checkfastpath=true (not false), as underlying slice/map type may be fast-path
+			e.encodeValue(reflect.ValueOf(iv), nil, true)
+		}
+	}
+}
+
+func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn, checkFastpath bool) {
+	// if a valid fn is passed, it MUST BE for the dereferenced type of rv
+	var sptr uintptr
+	var rvp reflect.Value
+	var rvpValid bool
+TOP:
+	switch rv.Kind() {
+	case reflect.Ptr:
+		if rv.IsNil() {
+			e.e.EncodeNil()
+			return
+		}
+		rvpValid = true
+		rvp = rv
+		rv = rv.Elem()
+		if e.h.CheckCircularRef && rv.Kind() == reflect.Struct {
+			// TODO: Movable pointers will be an issue here. Future problem.
+			sptr = rv.UnsafeAddr()
+			break TOP
+		}
+		goto TOP
+	case reflect.Interface:
+		if rv.IsNil() {
+			e.e.EncodeNil()
+			return
+		}
+		rv = rv.Elem()
+		goto TOP
+	case reflect.Slice, reflect.Map:
+		if rv.IsNil() {
+			e.e.EncodeNil()
+			return
+		}
+	case reflect.Invalid, reflect.Func:
+		e.e.EncodeNil()
+		return
+	}
+
+	if sptr != 0 && (&e.ci).add(sptr) {
+		e.errorf("circular reference found: # %d", sptr)
+	}
+
+	if fn == nil {
+		rt := rv.Type()
+		// always pass checkCodecSelfer=true, in case T or ****T is passed, where *T is a Selfer
+		fn = e.cfer().get(rt, checkFastpath, true)
+	}
+	if fn.i.addrE {
+		if rvpValid {
+			fn.fe(e, &fn.i, rvp)
+		} else if rv.CanAddr() {
+			fn.fe(e, &fn.i, rv.Addr())
+		} else {
+			rv2 := reflect.New(rv.Type())
+			rv2.Elem().Set(rv)
+			fn.fe(e, &fn.i, rv2)
+		}
+	} else {
+		fn.fe(e, &fn.i, rv)
+	}
+	if sptr != 0 {
+		(&e.ci).remove(sptr)
+	}
+}
+
+func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) {
+	if fnerr != nil {
+		panic(fnerr)
+	}
+	if bs == nil {
+		e.e.EncodeNil()
+	} else if asis {
+		e.asis(bs)
+	} else {
+		e.e.EncodeStringBytes(c, bs)
+	}
+}
+
+func (e *Encoder) asis(v []byte) {
+	if e.isas {
+		e.as.EncodeAsis(v)
+	} else {
+		e.w.writeb(v)
+	}
+}
+
+func (e *Encoder) rawBytes(vv Raw) {
+	v := []byte(vv)
+	if !e.h.Raw {
+		e.errorf("Raw values cannot be encoded: %v", v)
+	}
+	e.asis(v)
+}
+
+func (e *Encoder) wrapErrstr(v interface{}, err *error) {
+	*err = fmt.Errorf("%s encode error: %v", e.hh.Name(), v)
+}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.generated.go b/vendor/github.com/ugorji/go/codec/fast-path.generated.go
new file mode 100644
index 0000000..87f2562
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/fast-path.generated.go
@@ -0,0 +1,34522 @@
+// +build !notfastpath
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from fast-path.go.tmpl - DO NOT EDIT.
+
+package codec
+
+// Fast path functions try to create a fast path encode or decode implementation
+// for common maps and slices.
+//
+// We define the functions and register then in this single file
+// so as not to pollute the encode.go and decode.go, and create a dependency in there.
+// This file can be omitted without causing a build failure.
+//
+// The advantage of fast paths is:
+//	  - Many calls bypass reflection altogether
+//
+// Currently support
+//	  - slice of all builtin types,
+//	  - map of all builtin types to string or interface value
+//	  - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
+// This should provide adequate "typical" implementations.
+//
+// Note that fast track decode functions must handle values for which an address cannot be obtained.
+// For example:
+//	 m2 := map[string]int{}
+//	 p2 := []interface{}{m2}
+//	 // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
+//
+
+import (
+	"reflect"
+	"sort"
+)
+
+const fastpathEnabled = true
+
+type fastpathT struct{}
+
+var fastpathTV fastpathT
+
+type fastpathE struct {
+	rtid  uintptr
+	rt    reflect.Type
+	encfn func(*Encoder, *codecFnInfo, reflect.Value)
+	decfn func(*Decoder, *codecFnInfo, reflect.Value)
+}
+
+type fastpathA [271]fastpathE
+
+func (x *fastpathA) index(rtid uintptr) int {
+	// use binary search to grab the index (adapted from sort/search.go)
+	h, i, j := 0, 0, 271 // len(x)
+	for i < j {
+		h = i + (j-i)/2
+		if x[h].rtid < rtid {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	if i < 271 && x[i].rtid == rtid {
+		return i
+	}
+	return -1
+}
+
+type fastpathAslice []fastpathE
+
+func (x fastpathAslice) Len() int           { return len(x) }
+func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
+func (x fastpathAslice) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+
+var fastpathAV fastpathA
+
+// due to possible initialization loop error, make fastpath in an init()
+func init() {
+	i := 0
+	fn := func(v interface{},
+		fe func(*Encoder, *codecFnInfo, reflect.Value),
+		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
+		xrt := reflect.TypeOf(v)
+		xptr := rt2id(xrt)
+		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
+		i++
+		return
+	}
+
+	fn([]interface{}(nil), (*Encoder).fastpathEncSliceIntfR, (*Decoder).fastpathDecSliceIntfR)
+	fn([]string(nil), (*Encoder).fastpathEncSliceStringR, (*Decoder).fastpathDecSliceStringR)
+	fn([]float32(nil), (*Encoder).fastpathEncSliceFloat32R, (*Decoder).fastpathDecSliceFloat32R)
+	fn([]float64(nil), (*Encoder).fastpathEncSliceFloat64R, (*Decoder).fastpathDecSliceFloat64R)
+	fn([]uint(nil), (*Encoder).fastpathEncSliceUintR, (*Decoder).fastpathDecSliceUintR)
+	fn([]uint16(nil), (*Encoder).fastpathEncSliceUint16R, (*Decoder).fastpathDecSliceUint16R)
+	fn([]uint32(nil), (*Encoder).fastpathEncSliceUint32R, (*Decoder).fastpathDecSliceUint32R)
+	fn([]uint64(nil), (*Encoder).fastpathEncSliceUint64R, (*Decoder).fastpathDecSliceUint64R)
+	fn([]uintptr(nil), (*Encoder).fastpathEncSliceUintptrR, (*Decoder).fastpathDecSliceUintptrR)
+	fn([]int(nil), (*Encoder).fastpathEncSliceIntR, (*Decoder).fastpathDecSliceIntR)
+	fn([]int8(nil), (*Encoder).fastpathEncSliceInt8R, (*Decoder).fastpathDecSliceInt8R)
+	fn([]int16(nil), (*Encoder).fastpathEncSliceInt16R, (*Decoder).fastpathDecSliceInt16R)
+	fn([]int32(nil), (*Encoder).fastpathEncSliceInt32R, (*Decoder).fastpathDecSliceInt32R)
+	fn([]int64(nil), (*Encoder).fastpathEncSliceInt64R, (*Decoder).fastpathDecSliceInt64R)
+	fn([]bool(nil), (*Encoder).fastpathEncSliceBoolR, (*Decoder).fastpathDecSliceBoolR)
+
+	fn(map[interface{}]interface{}(nil), (*Encoder).fastpathEncMapIntfIntfR, (*Decoder).fastpathDecMapIntfIntfR)
+	fn(map[interface{}]string(nil), (*Encoder).fastpathEncMapIntfStringR, (*Decoder).fastpathDecMapIntfStringR)
+	fn(map[interface{}]uint(nil), (*Encoder).fastpathEncMapIntfUintR, (*Decoder).fastpathDecMapIntfUintR)
+	fn(map[interface{}]uint8(nil), (*Encoder).fastpathEncMapIntfUint8R, (*Decoder).fastpathDecMapIntfUint8R)
+	fn(map[interface{}]uint16(nil), (*Encoder).fastpathEncMapIntfUint16R, (*Decoder).fastpathDecMapIntfUint16R)
+	fn(map[interface{}]uint32(nil), (*Encoder).fastpathEncMapIntfUint32R, (*Decoder).fastpathDecMapIntfUint32R)
+	fn(map[interface{}]uint64(nil), (*Encoder).fastpathEncMapIntfUint64R, (*Decoder).fastpathDecMapIntfUint64R)
+	fn(map[interface{}]uintptr(nil), (*Encoder).fastpathEncMapIntfUintptrR, (*Decoder).fastpathDecMapIntfUintptrR)
+	fn(map[interface{}]int(nil), (*Encoder).fastpathEncMapIntfIntR, (*Decoder).fastpathDecMapIntfIntR)
+	fn(map[interface{}]int8(nil), (*Encoder).fastpathEncMapIntfInt8R, (*Decoder).fastpathDecMapIntfInt8R)
+	fn(map[interface{}]int16(nil), (*Encoder).fastpathEncMapIntfInt16R, (*Decoder).fastpathDecMapIntfInt16R)
+	fn(map[interface{}]int32(nil), (*Encoder).fastpathEncMapIntfInt32R, (*Decoder).fastpathDecMapIntfInt32R)
+	fn(map[interface{}]int64(nil), (*Encoder).fastpathEncMapIntfInt64R, (*Decoder).fastpathDecMapIntfInt64R)
+	fn(map[interface{}]float32(nil), (*Encoder).fastpathEncMapIntfFloat32R, (*Decoder).fastpathDecMapIntfFloat32R)
+	fn(map[interface{}]float64(nil), (*Encoder).fastpathEncMapIntfFloat64R, (*Decoder).fastpathDecMapIntfFloat64R)
+	fn(map[interface{}]bool(nil), (*Encoder).fastpathEncMapIntfBoolR, (*Decoder).fastpathDecMapIntfBoolR)
+	fn(map[string]interface{}(nil), (*Encoder).fastpathEncMapStringIntfR, (*Decoder).fastpathDecMapStringIntfR)
+	fn(map[string]string(nil), (*Encoder).fastpathEncMapStringStringR, (*Decoder).fastpathDecMapStringStringR)
+	fn(map[string]uint(nil), (*Encoder).fastpathEncMapStringUintR, (*Decoder).fastpathDecMapStringUintR)
+	fn(map[string]uint8(nil), (*Encoder).fastpathEncMapStringUint8R, (*Decoder).fastpathDecMapStringUint8R)
+	fn(map[string]uint16(nil), (*Encoder).fastpathEncMapStringUint16R, (*Decoder).fastpathDecMapStringUint16R)
+	fn(map[string]uint32(nil), (*Encoder).fastpathEncMapStringUint32R, (*Decoder).fastpathDecMapStringUint32R)
+	fn(map[string]uint64(nil), (*Encoder).fastpathEncMapStringUint64R, (*Decoder).fastpathDecMapStringUint64R)
+	fn(map[string]uintptr(nil), (*Encoder).fastpathEncMapStringUintptrR, (*Decoder).fastpathDecMapStringUintptrR)
+	fn(map[string]int(nil), (*Encoder).fastpathEncMapStringIntR, (*Decoder).fastpathDecMapStringIntR)
+	fn(map[string]int8(nil), (*Encoder).fastpathEncMapStringInt8R, (*Decoder).fastpathDecMapStringInt8R)
+	fn(map[string]int16(nil), (*Encoder).fastpathEncMapStringInt16R, (*Decoder).fastpathDecMapStringInt16R)
+	fn(map[string]int32(nil), (*Encoder).fastpathEncMapStringInt32R, (*Decoder).fastpathDecMapStringInt32R)
+	fn(map[string]int64(nil), (*Encoder).fastpathEncMapStringInt64R, (*Decoder).fastpathDecMapStringInt64R)
+	fn(map[string]float32(nil), (*Encoder).fastpathEncMapStringFloat32R, (*Decoder).fastpathDecMapStringFloat32R)
+	fn(map[string]float64(nil), (*Encoder).fastpathEncMapStringFloat64R, (*Decoder).fastpathDecMapStringFloat64R)
+	fn(map[string]bool(nil), (*Encoder).fastpathEncMapStringBoolR, (*Decoder).fastpathDecMapStringBoolR)
+	fn(map[float32]interface{}(nil), (*Encoder).fastpathEncMapFloat32IntfR, (*Decoder).fastpathDecMapFloat32IntfR)
+	fn(map[float32]string(nil), (*Encoder).fastpathEncMapFloat32StringR, (*Decoder).fastpathDecMapFloat32StringR)
+	fn(map[float32]uint(nil), (*Encoder).fastpathEncMapFloat32UintR, (*Decoder).fastpathDecMapFloat32UintR)
+	fn(map[float32]uint8(nil), (*Encoder).fastpathEncMapFloat32Uint8R, (*Decoder).fastpathDecMapFloat32Uint8R)
+	fn(map[float32]uint16(nil), (*Encoder).fastpathEncMapFloat32Uint16R, (*Decoder).fastpathDecMapFloat32Uint16R)
+	fn(map[float32]uint32(nil), (*Encoder).fastpathEncMapFloat32Uint32R, (*Decoder).fastpathDecMapFloat32Uint32R)
+	fn(map[float32]uint64(nil), (*Encoder).fastpathEncMapFloat32Uint64R, (*Decoder).fastpathDecMapFloat32Uint64R)
+	fn(map[float32]uintptr(nil), (*Encoder).fastpathEncMapFloat32UintptrR, (*Decoder).fastpathDecMapFloat32UintptrR)
+	fn(map[float32]int(nil), (*Encoder).fastpathEncMapFloat32IntR, (*Decoder).fastpathDecMapFloat32IntR)
+	fn(map[float32]int8(nil), (*Encoder).fastpathEncMapFloat32Int8R, (*Decoder).fastpathDecMapFloat32Int8R)
+	fn(map[float32]int16(nil), (*Encoder).fastpathEncMapFloat32Int16R, (*Decoder).fastpathDecMapFloat32Int16R)
+	fn(map[float32]int32(nil), (*Encoder).fastpathEncMapFloat32Int32R, (*Decoder).fastpathDecMapFloat32Int32R)
+	fn(map[float32]int64(nil), (*Encoder).fastpathEncMapFloat32Int64R, (*Decoder).fastpathDecMapFloat32Int64R)
+	fn(map[float32]float32(nil), (*Encoder).fastpathEncMapFloat32Float32R, (*Decoder).fastpathDecMapFloat32Float32R)
+	fn(map[float32]float64(nil), (*Encoder).fastpathEncMapFloat32Float64R, (*Decoder).fastpathDecMapFloat32Float64R)
+	fn(map[float32]bool(nil), (*Encoder).fastpathEncMapFloat32BoolR, (*Decoder).fastpathDecMapFloat32BoolR)
+	fn(map[float64]interface{}(nil), (*Encoder).fastpathEncMapFloat64IntfR, (*Decoder).fastpathDecMapFloat64IntfR)
+	fn(map[float64]string(nil), (*Encoder).fastpathEncMapFloat64StringR, (*Decoder).fastpathDecMapFloat64StringR)
+	fn(map[float64]uint(nil), (*Encoder).fastpathEncMapFloat64UintR, (*Decoder).fastpathDecMapFloat64UintR)
+	fn(map[float64]uint8(nil), (*Encoder).fastpathEncMapFloat64Uint8R, (*Decoder).fastpathDecMapFloat64Uint8R)
+	fn(map[float64]uint16(nil), (*Encoder).fastpathEncMapFloat64Uint16R, (*Decoder).fastpathDecMapFloat64Uint16R)
+	fn(map[float64]uint32(nil), (*Encoder).fastpathEncMapFloat64Uint32R, (*Decoder).fastpathDecMapFloat64Uint32R)
+	fn(map[float64]uint64(nil), (*Encoder).fastpathEncMapFloat64Uint64R, (*Decoder).fastpathDecMapFloat64Uint64R)
+	fn(map[float64]uintptr(nil), (*Encoder).fastpathEncMapFloat64UintptrR, (*Decoder).fastpathDecMapFloat64UintptrR)
+	fn(map[float64]int(nil), (*Encoder).fastpathEncMapFloat64IntR, (*Decoder).fastpathDecMapFloat64IntR)
+	fn(map[float64]int8(nil), (*Encoder).fastpathEncMapFloat64Int8R, (*Decoder).fastpathDecMapFloat64Int8R)
+	fn(map[float64]int16(nil), (*Encoder).fastpathEncMapFloat64Int16R, (*Decoder).fastpathDecMapFloat64Int16R)
+	fn(map[float64]int32(nil), (*Encoder).fastpathEncMapFloat64Int32R, (*Decoder).fastpathDecMapFloat64Int32R)
+	fn(map[float64]int64(nil), (*Encoder).fastpathEncMapFloat64Int64R, (*Decoder).fastpathDecMapFloat64Int64R)
+	fn(map[float64]float32(nil), (*Encoder).fastpathEncMapFloat64Float32R, (*Decoder).fastpathDecMapFloat64Float32R)
+	fn(map[float64]float64(nil), (*Encoder).fastpathEncMapFloat64Float64R, (*Decoder).fastpathDecMapFloat64Float64R)
+	fn(map[float64]bool(nil), (*Encoder).fastpathEncMapFloat64BoolR, (*Decoder).fastpathDecMapFloat64BoolR)
+	fn(map[uint]interface{}(nil), (*Encoder).fastpathEncMapUintIntfR, (*Decoder).fastpathDecMapUintIntfR)
+	fn(map[uint]string(nil), (*Encoder).fastpathEncMapUintStringR, (*Decoder).fastpathDecMapUintStringR)
+	fn(map[uint]uint(nil), (*Encoder).fastpathEncMapUintUintR, (*Decoder).fastpathDecMapUintUintR)
+	fn(map[uint]uint8(nil), (*Encoder).fastpathEncMapUintUint8R, (*Decoder).fastpathDecMapUintUint8R)
+	fn(map[uint]uint16(nil), (*Encoder).fastpathEncMapUintUint16R, (*Decoder).fastpathDecMapUintUint16R)
+	fn(map[uint]uint32(nil), (*Encoder).fastpathEncMapUintUint32R, (*Decoder).fastpathDecMapUintUint32R)
+	fn(map[uint]uint64(nil), (*Encoder).fastpathEncMapUintUint64R, (*Decoder).fastpathDecMapUintUint64R)
+	fn(map[uint]uintptr(nil), (*Encoder).fastpathEncMapUintUintptrR, (*Decoder).fastpathDecMapUintUintptrR)
+	fn(map[uint]int(nil), (*Encoder).fastpathEncMapUintIntR, (*Decoder).fastpathDecMapUintIntR)
+	fn(map[uint]int8(nil), (*Encoder).fastpathEncMapUintInt8R, (*Decoder).fastpathDecMapUintInt8R)
+	fn(map[uint]int16(nil), (*Encoder).fastpathEncMapUintInt16R, (*Decoder).fastpathDecMapUintInt16R)
+	fn(map[uint]int32(nil), (*Encoder).fastpathEncMapUintInt32R, (*Decoder).fastpathDecMapUintInt32R)
+	fn(map[uint]int64(nil), (*Encoder).fastpathEncMapUintInt64R, (*Decoder).fastpathDecMapUintInt64R)
+	fn(map[uint]float32(nil), (*Encoder).fastpathEncMapUintFloat32R, (*Decoder).fastpathDecMapUintFloat32R)
+	fn(map[uint]float64(nil), (*Encoder).fastpathEncMapUintFloat64R, (*Decoder).fastpathDecMapUintFloat64R)
+	fn(map[uint]bool(nil), (*Encoder).fastpathEncMapUintBoolR, (*Decoder).fastpathDecMapUintBoolR)
+	fn(map[uint8]interface{}(nil), (*Encoder).fastpathEncMapUint8IntfR, (*Decoder).fastpathDecMapUint8IntfR)
+	fn(map[uint8]string(nil), (*Encoder).fastpathEncMapUint8StringR, (*Decoder).fastpathDecMapUint8StringR)
+	fn(map[uint8]uint(nil), (*Encoder).fastpathEncMapUint8UintR, (*Decoder).fastpathDecMapUint8UintR)
+	fn(map[uint8]uint8(nil), (*Encoder).fastpathEncMapUint8Uint8R, (*Decoder).fastpathDecMapUint8Uint8R)
+	fn(map[uint8]uint16(nil), (*Encoder).fastpathEncMapUint8Uint16R, (*Decoder).fastpathDecMapUint8Uint16R)
+	fn(map[uint8]uint32(nil), (*Encoder).fastpathEncMapUint8Uint32R, (*Decoder).fastpathDecMapUint8Uint32R)
+	fn(map[uint8]uint64(nil), (*Encoder).fastpathEncMapUint8Uint64R, (*Decoder).fastpathDecMapUint8Uint64R)
+	fn(map[uint8]uintptr(nil), (*Encoder).fastpathEncMapUint8UintptrR, (*Decoder).fastpathDecMapUint8UintptrR)
+	fn(map[uint8]int(nil), (*Encoder).fastpathEncMapUint8IntR, (*Decoder).fastpathDecMapUint8IntR)
+	fn(map[uint8]int8(nil), (*Encoder).fastpathEncMapUint8Int8R, (*Decoder).fastpathDecMapUint8Int8R)
+	fn(map[uint8]int16(nil), (*Encoder).fastpathEncMapUint8Int16R, (*Decoder).fastpathDecMapUint8Int16R)
+	fn(map[uint8]int32(nil), (*Encoder).fastpathEncMapUint8Int32R, (*Decoder).fastpathDecMapUint8Int32R)
+	fn(map[uint8]int64(nil), (*Encoder).fastpathEncMapUint8Int64R, (*Decoder).fastpathDecMapUint8Int64R)
+	fn(map[uint8]float32(nil), (*Encoder).fastpathEncMapUint8Float32R, (*Decoder).fastpathDecMapUint8Float32R)
+	fn(map[uint8]float64(nil), (*Encoder).fastpathEncMapUint8Float64R, (*Decoder).fastpathDecMapUint8Float64R)
+	fn(map[uint8]bool(nil), (*Encoder).fastpathEncMapUint8BoolR, (*Decoder).fastpathDecMapUint8BoolR)
+	fn(map[uint16]interface{}(nil), (*Encoder).fastpathEncMapUint16IntfR, (*Decoder).fastpathDecMapUint16IntfR)
+	fn(map[uint16]string(nil), (*Encoder).fastpathEncMapUint16StringR, (*Decoder).fastpathDecMapUint16StringR)
+	fn(map[uint16]uint(nil), (*Encoder).fastpathEncMapUint16UintR, (*Decoder).fastpathDecMapUint16UintR)
+	fn(map[uint16]uint8(nil), (*Encoder).fastpathEncMapUint16Uint8R, (*Decoder).fastpathDecMapUint16Uint8R)
+	fn(map[uint16]uint16(nil), (*Encoder).fastpathEncMapUint16Uint16R, (*Decoder).fastpathDecMapUint16Uint16R)
+	fn(map[uint16]uint32(nil), (*Encoder).fastpathEncMapUint16Uint32R, (*Decoder).fastpathDecMapUint16Uint32R)
+	fn(map[uint16]uint64(nil), (*Encoder).fastpathEncMapUint16Uint64R, (*Decoder).fastpathDecMapUint16Uint64R)
+	fn(map[uint16]uintptr(nil), (*Encoder).fastpathEncMapUint16UintptrR, (*Decoder).fastpathDecMapUint16UintptrR)
+	fn(map[uint16]int(nil), (*Encoder).fastpathEncMapUint16IntR, (*Decoder).fastpathDecMapUint16IntR)
+	fn(map[uint16]int8(nil), (*Encoder).fastpathEncMapUint16Int8R, (*Decoder).fastpathDecMapUint16Int8R)
+	fn(map[uint16]int16(nil), (*Encoder).fastpathEncMapUint16Int16R, (*Decoder).fastpathDecMapUint16Int16R)
+	fn(map[uint16]int32(nil), (*Encoder).fastpathEncMapUint16Int32R, (*Decoder).fastpathDecMapUint16Int32R)
+	fn(map[uint16]int64(nil), (*Encoder).fastpathEncMapUint16Int64R, (*Decoder).fastpathDecMapUint16Int64R)
+	fn(map[uint16]float32(nil), (*Encoder).fastpathEncMapUint16Float32R, (*Decoder).fastpathDecMapUint16Float32R)
+	fn(map[uint16]float64(nil), (*Encoder).fastpathEncMapUint16Float64R, (*Decoder).fastpathDecMapUint16Float64R)
+	fn(map[uint16]bool(nil), (*Encoder).fastpathEncMapUint16BoolR, (*Decoder).fastpathDecMapUint16BoolR)
+	fn(map[uint32]interface{}(nil), (*Encoder).fastpathEncMapUint32IntfR, (*Decoder).fastpathDecMapUint32IntfR)
+	fn(map[uint32]string(nil), (*Encoder).fastpathEncMapUint32StringR, (*Decoder).fastpathDecMapUint32StringR)
+	fn(map[uint32]uint(nil), (*Encoder).fastpathEncMapUint32UintR, (*Decoder).fastpathDecMapUint32UintR)
+	fn(map[uint32]uint8(nil), (*Encoder).fastpathEncMapUint32Uint8R, (*Decoder).fastpathDecMapUint32Uint8R)
+	fn(map[uint32]uint16(nil), (*Encoder).fastpathEncMapUint32Uint16R, (*Decoder).fastpathDecMapUint32Uint16R)
+	fn(map[uint32]uint32(nil), (*Encoder).fastpathEncMapUint32Uint32R, (*Decoder).fastpathDecMapUint32Uint32R)
+	fn(map[uint32]uint64(nil), (*Encoder).fastpathEncMapUint32Uint64R, (*Decoder).fastpathDecMapUint32Uint64R)
+	fn(map[uint32]uintptr(nil), (*Encoder).fastpathEncMapUint32UintptrR, (*Decoder).fastpathDecMapUint32UintptrR)
+	fn(map[uint32]int(nil), (*Encoder).fastpathEncMapUint32IntR, (*Decoder).fastpathDecMapUint32IntR)
+	fn(map[uint32]int8(nil), (*Encoder).fastpathEncMapUint32Int8R, (*Decoder).fastpathDecMapUint32Int8R)
+	fn(map[uint32]int16(nil), (*Encoder).fastpathEncMapUint32Int16R, (*Decoder).fastpathDecMapUint32Int16R)
+	fn(map[uint32]int32(nil), (*Encoder).fastpathEncMapUint32Int32R, (*Decoder).fastpathDecMapUint32Int32R)
+	fn(map[uint32]int64(nil), (*Encoder).fastpathEncMapUint32Int64R, (*Decoder).fastpathDecMapUint32Int64R)
+	fn(map[uint32]float32(nil), (*Encoder).fastpathEncMapUint32Float32R, (*Decoder).fastpathDecMapUint32Float32R)
+	fn(map[uint32]float64(nil), (*Encoder).fastpathEncMapUint32Float64R, (*Decoder).fastpathDecMapUint32Float64R)
+	fn(map[uint32]bool(nil), (*Encoder).fastpathEncMapUint32BoolR, (*Decoder).fastpathDecMapUint32BoolR)
+	fn(map[uint64]interface{}(nil), (*Encoder).fastpathEncMapUint64IntfR, (*Decoder).fastpathDecMapUint64IntfR)
+	fn(map[uint64]string(nil), (*Encoder).fastpathEncMapUint64StringR, (*Decoder).fastpathDecMapUint64StringR)
+	fn(map[uint64]uint(nil), (*Encoder).fastpathEncMapUint64UintR, (*Decoder).fastpathDecMapUint64UintR)
+	fn(map[uint64]uint8(nil), (*Encoder).fastpathEncMapUint64Uint8R, (*Decoder).fastpathDecMapUint64Uint8R)
+	fn(map[uint64]uint16(nil), (*Encoder).fastpathEncMapUint64Uint16R, (*Decoder).fastpathDecMapUint64Uint16R)
+	fn(map[uint64]uint32(nil), (*Encoder).fastpathEncMapUint64Uint32R, (*Decoder).fastpathDecMapUint64Uint32R)
+	fn(map[uint64]uint64(nil), (*Encoder).fastpathEncMapUint64Uint64R, (*Decoder).fastpathDecMapUint64Uint64R)
+	fn(map[uint64]uintptr(nil), (*Encoder).fastpathEncMapUint64UintptrR, (*Decoder).fastpathDecMapUint64UintptrR)
+	fn(map[uint64]int(nil), (*Encoder).fastpathEncMapUint64IntR, (*Decoder).fastpathDecMapUint64IntR)
+	fn(map[uint64]int8(nil), (*Encoder).fastpathEncMapUint64Int8R, (*Decoder).fastpathDecMapUint64Int8R)
+	fn(map[uint64]int16(nil), (*Encoder).fastpathEncMapUint64Int16R, (*Decoder).fastpathDecMapUint64Int16R)
+	fn(map[uint64]int32(nil), (*Encoder).fastpathEncMapUint64Int32R, (*Decoder).fastpathDecMapUint64Int32R)
+	fn(map[uint64]int64(nil), (*Encoder).fastpathEncMapUint64Int64R, (*Decoder).fastpathDecMapUint64Int64R)
+	fn(map[uint64]float32(nil), (*Encoder).fastpathEncMapUint64Float32R, (*Decoder).fastpathDecMapUint64Float32R)
+	fn(map[uint64]float64(nil), (*Encoder).fastpathEncMapUint64Float64R, (*Decoder).fastpathDecMapUint64Float64R)
+	fn(map[uint64]bool(nil), (*Encoder).fastpathEncMapUint64BoolR, (*Decoder).fastpathDecMapUint64BoolR)
+	fn(map[uintptr]interface{}(nil), (*Encoder).fastpathEncMapUintptrIntfR, (*Decoder).fastpathDecMapUintptrIntfR)
+	fn(map[uintptr]string(nil), (*Encoder).fastpathEncMapUintptrStringR, (*Decoder).fastpathDecMapUintptrStringR)
+	fn(map[uintptr]uint(nil), (*Encoder).fastpathEncMapUintptrUintR, (*Decoder).fastpathDecMapUintptrUintR)
+	fn(map[uintptr]uint8(nil), (*Encoder).fastpathEncMapUintptrUint8R, (*Decoder).fastpathDecMapUintptrUint8R)
+	fn(map[uintptr]uint16(nil), (*Encoder).fastpathEncMapUintptrUint16R, (*Decoder).fastpathDecMapUintptrUint16R)
+	fn(map[uintptr]uint32(nil), (*Encoder).fastpathEncMapUintptrUint32R, (*Decoder).fastpathDecMapUintptrUint32R)
+	fn(map[uintptr]uint64(nil), (*Encoder).fastpathEncMapUintptrUint64R, (*Decoder).fastpathDecMapUintptrUint64R)
+	fn(map[uintptr]uintptr(nil), (*Encoder).fastpathEncMapUintptrUintptrR, (*Decoder).fastpathDecMapUintptrUintptrR)
+	fn(map[uintptr]int(nil), (*Encoder).fastpathEncMapUintptrIntR, (*Decoder).fastpathDecMapUintptrIntR)
+	fn(map[uintptr]int8(nil), (*Encoder).fastpathEncMapUintptrInt8R, (*Decoder).fastpathDecMapUintptrInt8R)
+	fn(map[uintptr]int16(nil), (*Encoder).fastpathEncMapUintptrInt16R, (*Decoder).fastpathDecMapUintptrInt16R)
+	fn(map[uintptr]int32(nil), (*Encoder).fastpathEncMapUintptrInt32R, (*Decoder).fastpathDecMapUintptrInt32R)
+	fn(map[uintptr]int64(nil), (*Encoder).fastpathEncMapUintptrInt64R, (*Decoder).fastpathDecMapUintptrInt64R)
+	fn(map[uintptr]float32(nil), (*Encoder).fastpathEncMapUintptrFloat32R, (*Decoder).fastpathDecMapUintptrFloat32R)
+	fn(map[uintptr]float64(nil), (*Encoder).fastpathEncMapUintptrFloat64R, (*Decoder).fastpathDecMapUintptrFloat64R)
+	fn(map[uintptr]bool(nil), (*Encoder).fastpathEncMapUintptrBoolR, (*Decoder).fastpathDecMapUintptrBoolR)
+	fn(map[int]interface{}(nil), (*Encoder).fastpathEncMapIntIntfR, (*Decoder).fastpathDecMapIntIntfR)
+	fn(map[int]string(nil), (*Encoder).fastpathEncMapIntStringR, (*Decoder).fastpathDecMapIntStringR)
+	fn(map[int]uint(nil), (*Encoder).fastpathEncMapIntUintR, (*Decoder).fastpathDecMapIntUintR)
+	fn(map[int]uint8(nil), (*Encoder).fastpathEncMapIntUint8R, (*Decoder).fastpathDecMapIntUint8R)
+	fn(map[int]uint16(nil), (*Encoder).fastpathEncMapIntUint16R, (*Decoder).fastpathDecMapIntUint16R)
+	fn(map[int]uint32(nil), (*Encoder).fastpathEncMapIntUint32R, (*Decoder).fastpathDecMapIntUint32R)
+	fn(map[int]uint64(nil), (*Encoder).fastpathEncMapIntUint64R, (*Decoder).fastpathDecMapIntUint64R)
+	fn(map[int]uintptr(nil), (*Encoder).fastpathEncMapIntUintptrR, (*Decoder).fastpathDecMapIntUintptrR)
+	fn(map[int]int(nil), (*Encoder).fastpathEncMapIntIntR, (*Decoder).fastpathDecMapIntIntR)
+	fn(map[int]int8(nil), (*Encoder).fastpathEncMapIntInt8R, (*Decoder).fastpathDecMapIntInt8R)
+	fn(map[int]int16(nil), (*Encoder).fastpathEncMapIntInt16R, (*Decoder).fastpathDecMapIntInt16R)
+	fn(map[int]int32(nil), (*Encoder).fastpathEncMapIntInt32R, (*Decoder).fastpathDecMapIntInt32R)
+	fn(map[int]int64(nil), (*Encoder).fastpathEncMapIntInt64R, (*Decoder).fastpathDecMapIntInt64R)
+	fn(map[int]float32(nil), (*Encoder).fastpathEncMapIntFloat32R, (*Decoder).fastpathDecMapIntFloat32R)
+	fn(map[int]float64(nil), (*Encoder).fastpathEncMapIntFloat64R, (*Decoder).fastpathDecMapIntFloat64R)
+	fn(map[int]bool(nil), (*Encoder).fastpathEncMapIntBoolR, (*Decoder).fastpathDecMapIntBoolR)
+	fn(map[int8]interface{}(nil), (*Encoder).fastpathEncMapInt8IntfR, (*Decoder).fastpathDecMapInt8IntfR)
+	fn(map[int8]string(nil), (*Encoder).fastpathEncMapInt8StringR, (*Decoder).fastpathDecMapInt8StringR)
+	fn(map[int8]uint(nil), (*Encoder).fastpathEncMapInt8UintR, (*Decoder).fastpathDecMapInt8UintR)
+	fn(map[int8]uint8(nil), (*Encoder).fastpathEncMapInt8Uint8R, (*Decoder).fastpathDecMapInt8Uint8R)
+	fn(map[int8]uint16(nil), (*Encoder).fastpathEncMapInt8Uint16R, (*Decoder).fastpathDecMapInt8Uint16R)
+	fn(map[int8]uint32(nil), (*Encoder).fastpathEncMapInt8Uint32R, (*Decoder).fastpathDecMapInt8Uint32R)
+	fn(map[int8]uint64(nil), (*Encoder).fastpathEncMapInt8Uint64R, (*Decoder).fastpathDecMapInt8Uint64R)
+	fn(map[int8]uintptr(nil), (*Encoder).fastpathEncMapInt8UintptrR, (*Decoder).fastpathDecMapInt8UintptrR)
+	fn(map[int8]int(nil), (*Encoder).fastpathEncMapInt8IntR, (*Decoder).fastpathDecMapInt8IntR)
+	fn(map[int8]int8(nil), (*Encoder).fastpathEncMapInt8Int8R, (*Decoder).fastpathDecMapInt8Int8R)
+	fn(map[int8]int16(nil), (*Encoder).fastpathEncMapInt8Int16R, (*Decoder).fastpathDecMapInt8Int16R)
+	fn(map[int8]int32(nil), (*Encoder).fastpathEncMapInt8Int32R, (*Decoder).fastpathDecMapInt8Int32R)
+	fn(map[int8]int64(nil), (*Encoder).fastpathEncMapInt8Int64R, (*Decoder).fastpathDecMapInt8Int64R)
+	fn(map[int8]float32(nil), (*Encoder).fastpathEncMapInt8Float32R, (*Decoder).fastpathDecMapInt8Float32R)
+	fn(map[int8]float64(nil), (*Encoder).fastpathEncMapInt8Float64R, (*Decoder).fastpathDecMapInt8Float64R)
+	fn(map[int8]bool(nil), (*Encoder).fastpathEncMapInt8BoolR, (*Decoder).fastpathDecMapInt8BoolR)
+	fn(map[int16]interface{}(nil), (*Encoder).fastpathEncMapInt16IntfR, (*Decoder).fastpathDecMapInt16IntfR)
+	fn(map[int16]string(nil), (*Encoder).fastpathEncMapInt16StringR, (*Decoder).fastpathDecMapInt16StringR)
+	fn(map[int16]uint(nil), (*Encoder).fastpathEncMapInt16UintR, (*Decoder).fastpathDecMapInt16UintR)
+	fn(map[int16]uint8(nil), (*Encoder).fastpathEncMapInt16Uint8R, (*Decoder).fastpathDecMapInt16Uint8R)
+	fn(map[int16]uint16(nil), (*Encoder).fastpathEncMapInt16Uint16R, (*Decoder).fastpathDecMapInt16Uint16R)
+	fn(map[int16]uint32(nil), (*Encoder).fastpathEncMapInt16Uint32R, (*Decoder).fastpathDecMapInt16Uint32R)
+	fn(map[int16]uint64(nil), (*Encoder).fastpathEncMapInt16Uint64R, (*Decoder).fastpathDecMapInt16Uint64R)
+	fn(map[int16]uintptr(nil), (*Encoder).fastpathEncMapInt16UintptrR, (*Decoder).fastpathDecMapInt16UintptrR)
+	fn(map[int16]int(nil), (*Encoder).fastpathEncMapInt16IntR, (*Decoder).fastpathDecMapInt16IntR)
+	fn(map[int16]int8(nil), (*Encoder).fastpathEncMapInt16Int8R, (*Decoder).fastpathDecMapInt16Int8R)
+	fn(map[int16]int16(nil), (*Encoder).fastpathEncMapInt16Int16R, (*Decoder).fastpathDecMapInt16Int16R)
+	fn(map[int16]int32(nil), (*Encoder).fastpathEncMapInt16Int32R, (*Decoder).fastpathDecMapInt16Int32R)
+	fn(map[int16]int64(nil), (*Encoder).fastpathEncMapInt16Int64R, (*Decoder).fastpathDecMapInt16Int64R)
+	fn(map[int16]float32(nil), (*Encoder).fastpathEncMapInt16Float32R, (*Decoder).fastpathDecMapInt16Float32R)
+	fn(map[int16]float64(nil), (*Encoder).fastpathEncMapInt16Float64R, (*Decoder).fastpathDecMapInt16Float64R)
+	fn(map[int16]bool(nil), (*Encoder).fastpathEncMapInt16BoolR, (*Decoder).fastpathDecMapInt16BoolR)
+	fn(map[int32]interface{}(nil), (*Encoder).fastpathEncMapInt32IntfR, (*Decoder).fastpathDecMapInt32IntfR)
+	fn(map[int32]string(nil), (*Encoder).fastpathEncMapInt32StringR, (*Decoder).fastpathDecMapInt32StringR)
+	fn(map[int32]uint(nil), (*Encoder).fastpathEncMapInt32UintR, (*Decoder).fastpathDecMapInt32UintR)
+	fn(map[int32]uint8(nil), (*Encoder).fastpathEncMapInt32Uint8R, (*Decoder).fastpathDecMapInt32Uint8R)
+	fn(map[int32]uint16(nil), (*Encoder).fastpathEncMapInt32Uint16R, (*Decoder).fastpathDecMapInt32Uint16R)
+	fn(map[int32]uint32(nil), (*Encoder).fastpathEncMapInt32Uint32R, (*Decoder).fastpathDecMapInt32Uint32R)
+	fn(map[int32]uint64(nil), (*Encoder).fastpathEncMapInt32Uint64R, (*Decoder).fastpathDecMapInt32Uint64R)
+	fn(map[int32]uintptr(nil), (*Encoder).fastpathEncMapInt32UintptrR, (*Decoder).fastpathDecMapInt32UintptrR)
+	fn(map[int32]int(nil), (*Encoder).fastpathEncMapInt32IntR, (*Decoder).fastpathDecMapInt32IntR)
+	fn(map[int32]int8(nil), (*Encoder).fastpathEncMapInt32Int8R, (*Decoder).fastpathDecMapInt32Int8R)
+	fn(map[int32]int16(nil), (*Encoder).fastpathEncMapInt32Int16R, (*Decoder).fastpathDecMapInt32Int16R)
+	fn(map[int32]int32(nil), (*Encoder).fastpathEncMapInt32Int32R, (*Decoder).fastpathDecMapInt32Int32R)
+	fn(map[int32]int64(nil), (*Encoder).fastpathEncMapInt32Int64R, (*Decoder).fastpathDecMapInt32Int64R)
+	fn(map[int32]float32(nil), (*Encoder).fastpathEncMapInt32Float32R, (*Decoder).fastpathDecMapInt32Float32R)
+	fn(map[int32]float64(nil), (*Encoder).fastpathEncMapInt32Float64R, (*Decoder).fastpathDecMapInt32Float64R)
+	fn(map[int32]bool(nil), (*Encoder).fastpathEncMapInt32BoolR, (*Decoder).fastpathDecMapInt32BoolR)
+	fn(map[int64]interface{}(nil), (*Encoder).fastpathEncMapInt64IntfR, (*Decoder).fastpathDecMapInt64IntfR)
+	fn(map[int64]string(nil), (*Encoder).fastpathEncMapInt64StringR, (*Decoder).fastpathDecMapInt64StringR)
+	fn(map[int64]uint(nil), (*Encoder).fastpathEncMapInt64UintR, (*Decoder).fastpathDecMapInt64UintR)
+	fn(map[int64]uint8(nil), (*Encoder).fastpathEncMapInt64Uint8R, (*Decoder).fastpathDecMapInt64Uint8R)
+	fn(map[int64]uint16(nil), (*Encoder).fastpathEncMapInt64Uint16R, (*Decoder).fastpathDecMapInt64Uint16R)
+	fn(map[int64]uint32(nil), (*Encoder).fastpathEncMapInt64Uint32R, (*Decoder).fastpathDecMapInt64Uint32R)
+	fn(map[int64]uint64(nil), (*Encoder).fastpathEncMapInt64Uint64R, (*Decoder).fastpathDecMapInt64Uint64R)
+	fn(map[int64]uintptr(nil), (*Encoder).fastpathEncMapInt64UintptrR, (*Decoder).fastpathDecMapInt64UintptrR)
+	fn(map[int64]int(nil), (*Encoder).fastpathEncMapInt64IntR, (*Decoder).fastpathDecMapInt64IntR)
+	fn(map[int64]int8(nil), (*Encoder).fastpathEncMapInt64Int8R, (*Decoder).fastpathDecMapInt64Int8R)
+	fn(map[int64]int16(nil), (*Encoder).fastpathEncMapInt64Int16R, (*Decoder).fastpathDecMapInt64Int16R)
+	fn(map[int64]int32(nil), (*Encoder).fastpathEncMapInt64Int32R, (*Decoder).fastpathDecMapInt64Int32R)
+	fn(map[int64]int64(nil), (*Encoder).fastpathEncMapInt64Int64R, (*Decoder).fastpathDecMapInt64Int64R)
+	fn(map[int64]float32(nil), (*Encoder).fastpathEncMapInt64Float32R, (*Decoder).fastpathDecMapInt64Float32R)
+	fn(map[int64]float64(nil), (*Encoder).fastpathEncMapInt64Float64R, (*Decoder).fastpathDecMapInt64Float64R)
+	fn(map[int64]bool(nil), (*Encoder).fastpathEncMapInt64BoolR, (*Decoder).fastpathDecMapInt64BoolR)
+	fn(map[bool]interface{}(nil), (*Encoder).fastpathEncMapBoolIntfR, (*Decoder).fastpathDecMapBoolIntfR)
+	fn(map[bool]string(nil), (*Encoder).fastpathEncMapBoolStringR, (*Decoder).fastpathDecMapBoolStringR)
+	fn(map[bool]uint(nil), (*Encoder).fastpathEncMapBoolUintR, (*Decoder).fastpathDecMapBoolUintR)
+	fn(map[bool]uint8(nil), (*Encoder).fastpathEncMapBoolUint8R, (*Decoder).fastpathDecMapBoolUint8R)
+	fn(map[bool]uint16(nil), (*Encoder).fastpathEncMapBoolUint16R, (*Decoder).fastpathDecMapBoolUint16R)
+	fn(map[bool]uint32(nil), (*Encoder).fastpathEncMapBoolUint32R, (*Decoder).fastpathDecMapBoolUint32R)
+	fn(map[bool]uint64(nil), (*Encoder).fastpathEncMapBoolUint64R, (*Decoder).fastpathDecMapBoolUint64R)
+	fn(map[bool]uintptr(nil), (*Encoder).fastpathEncMapBoolUintptrR, (*Decoder).fastpathDecMapBoolUintptrR)
+	fn(map[bool]int(nil), (*Encoder).fastpathEncMapBoolIntR, (*Decoder).fastpathDecMapBoolIntR)
+	fn(map[bool]int8(nil), (*Encoder).fastpathEncMapBoolInt8R, (*Decoder).fastpathDecMapBoolInt8R)
+	fn(map[bool]int16(nil), (*Encoder).fastpathEncMapBoolInt16R, (*Decoder).fastpathDecMapBoolInt16R)
+	fn(map[bool]int32(nil), (*Encoder).fastpathEncMapBoolInt32R, (*Decoder).fastpathDecMapBoolInt32R)
+	fn(map[bool]int64(nil), (*Encoder).fastpathEncMapBoolInt64R, (*Decoder).fastpathDecMapBoolInt64R)
+	fn(map[bool]float32(nil), (*Encoder).fastpathEncMapBoolFloat32R, (*Decoder).fastpathDecMapBoolFloat32R)
+	fn(map[bool]float64(nil), (*Encoder).fastpathEncMapBoolFloat64R, (*Decoder).fastpathDecMapBoolFloat64R)
+	fn(map[bool]bool(nil), (*Encoder).fastpathEncMapBoolBoolR, (*Decoder).fastpathDecMapBoolBoolR)
+
+	sort.Sort(fastpathAslice(fastpathAV[:]))
+}
+
+// -- encode
+
+// -- -- fast path type switch
+func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+
+	case []interface{}:
+		fastpathTV.EncSliceIntfV(v, e)
+	case *[]interface{}:
+		fastpathTV.EncSliceIntfV(*v, e)
+	case []string:
+		fastpathTV.EncSliceStringV(v, e)
+	case *[]string:
+		fastpathTV.EncSliceStringV(*v, e)
+	case []float32:
+		fastpathTV.EncSliceFloat32V(v, e)
+	case *[]float32:
+		fastpathTV.EncSliceFloat32V(*v, e)
+	case []float64:
+		fastpathTV.EncSliceFloat64V(v, e)
+	case *[]float64:
+		fastpathTV.EncSliceFloat64V(*v, e)
+	case []uint:
+		fastpathTV.EncSliceUintV(v, e)
+	case *[]uint:
+		fastpathTV.EncSliceUintV(*v, e)
+	case []uint16:
+		fastpathTV.EncSliceUint16V(v, e)
+	case *[]uint16:
+		fastpathTV.EncSliceUint16V(*v, e)
+	case []uint32:
+		fastpathTV.EncSliceUint32V(v, e)
+	case *[]uint32:
+		fastpathTV.EncSliceUint32V(*v, e)
+	case []uint64:
+		fastpathTV.EncSliceUint64V(v, e)
+	case *[]uint64:
+		fastpathTV.EncSliceUint64V(*v, e)
+	case []uintptr:
+		fastpathTV.EncSliceUintptrV(v, e)
+	case *[]uintptr:
+		fastpathTV.EncSliceUintptrV(*v, e)
+	case []int:
+		fastpathTV.EncSliceIntV(v, e)
+	case *[]int:
+		fastpathTV.EncSliceIntV(*v, e)
+	case []int8:
+		fastpathTV.EncSliceInt8V(v, e)
+	case *[]int8:
+		fastpathTV.EncSliceInt8V(*v, e)
+	case []int16:
+		fastpathTV.EncSliceInt16V(v, e)
+	case *[]int16:
+		fastpathTV.EncSliceInt16V(*v, e)
+	case []int32:
+		fastpathTV.EncSliceInt32V(v, e)
+	case *[]int32:
+		fastpathTV.EncSliceInt32V(*v, e)
+	case []int64:
+		fastpathTV.EncSliceInt64V(v, e)
+	case *[]int64:
+		fastpathTV.EncSliceInt64V(*v, e)
+	case []bool:
+		fastpathTV.EncSliceBoolV(v, e)
+	case *[]bool:
+		fastpathTV.EncSliceBoolV(*v, e)
+
+	case map[interface{}]interface{}:
+		fastpathTV.EncMapIntfIntfV(v, e)
+	case *map[interface{}]interface{}:
+		fastpathTV.EncMapIntfIntfV(*v, e)
+	case map[interface{}]string:
+		fastpathTV.EncMapIntfStringV(v, e)
+	case *map[interface{}]string:
+		fastpathTV.EncMapIntfStringV(*v, e)
+	case map[interface{}]uint:
+		fastpathTV.EncMapIntfUintV(v, e)
+	case *map[interface{}]uint:
+		fastpathTV.EncMapIntfUintV(*v, e)
+	case map[interface{}]uint8:
+		fastpathTV.EncMapIntfUint8V(v, e)
+	case *map[interface{}]uint8:
+		fastpathTV.EncMapIntfUint8V(*v, e)
+	case map[interface{}]uint16:
+		fastpathTV.EncMapIntfUint16V(v, e)
+	case *map[interface{}]uint16:
+		fastpathTV.EncMapIntfUint16V(*v, e)
+	case map[interface{}]uint32:
+		fastpathTV.EncMapIntfUint32V(v, e)
+	case *map[interface{}]uint32:
+		fastpathTV.EncMapIntfUint32V(*v, e)
+	case map[interface{}]uint64:
+		fastpathTV.EncMapIntfUint64V(v, e)
+	case *map[interface{}]uint64:
+		fastpathTV.EncMapIntfUint64V(*v, e)
+	case map[interface{}]uintptr:
+		fastpathTV.EncMapIntfUintptrV(v, e)
+	case *map[interface{}]uintptr:
+		fastpathTV.EncMapIntfUintptrV(*v, e)
+	case map[interface{}]int:
+		fastpathTV.EncMapIntfIntV(v, e)
+	case *map[interface{}]int:
+		fastpathTV.EncMapIntfIntV(*v, e)
+	case map[interface{}]int8:
+		fastpathTV.EncMapIntfInt8V(v, e)
+	case *map[interface{}]int8:
+		fastpathTV.EncMapIntfInt8V(*v, e)
+	case map[interface{}]int16:
+		fastpathTV.EncMapIntfInt16V(v, e)
+	case *map[interface{}]int16:
+		fastpathTV.EncMapIntfInt16V(*v, e)
+	case map[interface{}]int32:
+		fastpathTV.EncMapIntfInt32V(v, e)
+	case *map[interface{}]int32:
+		fastpathTV.EncMapIntfInt32V(*v, e)
+	case map[interface{}]int64:
+		fastpathTV.EncMapIntfInt64V(v, e)
+	case *map[interface{}]int64:
+		fastpathTV.EncMapIntfInt64V(*v, e)
+	case map[interface{}]float32:
+		fastpathTV.EncMapIntfFloat32V(v, e)
+	case *map[interface{}]float32:
+		fastpathTV.EncMapIntfFloat32V(*v, e)
+	case map[interface{}]float64:
+		fastpathTV.EncMapIntfFloat64V(v, e)
+	case *map[interface{}]float64:
+		fastpathTV.EncMapIntfFloat64V(*v, e)
+	case map[interface{}]bool:
+		fastpathTV.EncMapIntfBoolV(v, e)
+	case *map[interface{}]bool:
+		fastpathTV.EncMapIntfBoolV(*v, e)
+	case map[string]interface{}:
+		fastpathTV.EncMapStringIntfV(v, e)
+	case *map[string]interface{}:
+		fastpathTV.EncMapStringIntfV(*v, e)
+	case map[string]string:
+		fastpathTV.EncMapStringStringV(v, e)
+	case *map[string]string:
+		fastpathTV.EncMapStringStringV(*v, e)
+	case map[string]uint:
+		fastpathTV.EncMapStringUintV(v, e)
+	case *map[string]uint:
+		fastpathTV.EncMapStringUintV(*v, e)
+	case map[string]uint8:
+		fastpathTV.EncMapStringUint8V(v, e)
+	case *map[string]uint8:
+		fastpathTV.EncMapStringUint8V(*v, e)
+	case map[string]uint16:
+		fastpathTV.EncMapStringUint16V(v, e)
+	case *map[string]uint16:
+		fastpathTV.EncMapStringUint16V(*v, e)
+	case map[string]uint32:
+		fastpathTV.EncMapStringUint32V(v, e)
+	case *map[string]uint32:
+		fastpathTV.EncMapStringUint32V(*v, e)
+	case map[string]uint64:
+		fastpathTV.EncMapStringUint64V(v, e)
+	case *map[string]uint64:
+		fastpathTV.EncMapStringUint64V(*v, e)
+	case map[string]uintptr:
+		fastpathTV.EncMapStringUintptrV(v, e)
+	case *map[string]uintptr:
+		fastpathTV.EncMapStringUintptrV(*v, e)
+	case map[string]int:
+		fastpathTV.EncMapStringIntV(v, e)
+	case *map[string]int:
+		fastpathTV.EncMapStringIntV(*v, e)
+	case map[string]int8:
+		fastpathTV.EncMapStringInt8V(v, e)
+	case *map[string]int8:
+		fastpathTV.EncMapStringInt8V(*v, e)
+	case map[string]int16:
+		fastpathTV.EncMapStringInt16V(v, e)
+	case *map[string]int16:
+		fastpathTV.EncMapStringInt16V(*v, e)
+	case map[string]int32:
+		fastpathTV.EncMapStringInt32V(v, e)
+	case *map[string]int32:
+		fastpathTV.EncMapStringInt32V(*v, e)
+	case map[string]int64:
+		fastpathTV.EncMapStringInt64V(v, e)
+	case *map[string]int64:
+		fastpathTV.EncMapStringInt64V(*v, e)
+	case map[string]float32:
+		fastpathTV.EncMapStringFloat32V(v, e)
+	case *map[string]float32:
+		fastpathTV.EncMapStringFloat32V(*v, e)
+	case map[string]float64:
+		fastpathTV.EncMapStringFloat64V(v, e)
+	case *map[string]float64:
+		fastpathTV.EncMapStringFloat64V(*v, e)
+	case map[string]bool:
+		fastpathTV.EncMapStringBoolV(v, e)
+	case *map[string]bool:
+		fastpathTV.EncMapStringBoolV(*v, e)
+	case map[float32]interface{}:
+		fastpathTV.EncMapFloat32IntfV(v, e)
+	case *map[float32]interface{}:
+		fastpathTV.EncMapFloat32IntfV(*v, e)
+	case map[float32]string:
+		fastpathTV.EncMapFloat32StringV(v, e)
+	case *map[float32]string:
+		fastpathTV.EncMapFloat32StringV(*v, e)
+	case map[float32]uint:
+		fastpathTV.EncMapFloat32UintV(v, e)
+	case *map[float32]uint:
+		fastpathTV.EncMapFloat32UintV(*v, e)
+	case map[float32]uint8:
+		fastpathTV.EncMapFloat32Uint8V(v, e)
+	case *map[float32]uint8:
+		fastpathTV.EncMapFloat32Uint8V(*v, e)
+	case map[float32]uint16:
+		fastpathTV.EncMapFloat32Uint16V(v, e)
+	case *map[float32]uint16:
+		fastpathTV.EncMapFloat32Uint16V(*v, e)
+	case map[float32]uint32:
+		fastpathTV.EncMapFloat32Uint32V(v, e)
+	case *map[float32]uint32:
+		fastpathTV.EncMapFloat32Uint32V(*v, e)
+	case map[float32]uint64:
+		fastpathTV.EncMapFloat32Uint64V(v, e)
+	case *map[float32]uint64:
+		fastpathTV.EncMapFloat32Uint64V(*v, e)
+	case map[float32]uintptr:
+		fastpathTV.EncMapFloat32UintptrV(v, e)
+	case *map[float32]uintptr:
+		fastpathTV.EncMapFloat32UintptrV(*v, e)
+	case map[float32]int:
+		fastpathTV.EncMapFloat32IntV(v, e)
+	case *map[float32]int:
+		fastpathTV.EncMapFloat32IntV(*v, e)
+	case map[float32]int8:
+		fastpathTV.EncMapFloat32Int8V(v, e)
+	case *map[float32]int8:
+		fastpathTV.EncMapFloat32Int8V(*v, e)
+	case map[float32]int16:
+		fastpathTV.EncMapFloat32Int16V(v, e)
+	case *map[float32]int16:
+		fastpathTV.EncMapFloat32Int16V(*v, e)
+	case map[float32]int32:
+		fastpathTV.EncMapFloat32Int32V(v, e)
+	case *map[float32]int32:
+		fastpathTV.EncMapFloat32Int32V(*v, e)
+	case map[float32]int64:
+		fastpathTV.EncMapFloat32Int64V(v, e)
+	case *map[float32]int64:
+		fastpathTV.EncMapFloat32Int64V(*v, e)
+	case map[float32]float32:
+		fastpathTV.EncMapFloat32Float32V(v, e)
+	case *map[float32]float32:
+		fastpathTV.EncMapFloat32Float32V(*v, e)
+	case map[float32]float64:
+		fastpathTV.EncMapFloat32Float64V(v, e)
+	case *map[float32]float64:
+		fastpathTV.EncMapFloat32Float64V(*v, e)
+	case map[float32]bool:
+		fastpathTV.EncMapFloat32BoolV(v, e)
+	case *map[float32]bool:
+		fastpathTV.EncMapFloat32BoolV(*v, e)
+	case map[float64]interface{}:
+		fastpathTV.EncMapFloat64IntfV(v, e)
+	case *map[float64]interface{}:
+		fastpathTV.EncMapFloat64IntfV(*v, e)
+	case map[float64]string:
+		fastpathTV.EncMapFloat64StringV(v, e)
+	case *map[float64]string:
+		fastpathTV.EncMapFloat64StringV(*v, e)
+	case map[float64]uint:
+		fastpathTV.EncMapFloat64UintV(v, e)
+	case *map[float64]uint:
+		fastpathTV.EncMapFloat64UintV(*v, e)
+	case map[float64]uint8:
+		fastpathTV.EncMapFloat64Uint8V(v, e)
+	case *map[float64]uint8:
+		fastpathTV.EncMapFloat64Uint8V(*v, e)
+	case map[float64]uint16:
+		fastpathTV.EncMapFloat64Uint16V(v, e)
+	case *map[float64]uint16:
+		fastpathTV.EncMapFloat64Uint16V(*v, e)
+	case map[float64]uint32:
+		fastpathTV.EncMapFloat64Uint32V(v, e)
+	case *map[float64]uint32:
+		fastpathTV.EncMapFloat64Uint32V(*v, e)
+	case map[float64]uint64:
+		fastpathTV.EncMapFloat64Uint64V(v, e)
+	case *map[float64]uint64:
+		fastpathTV.EncMapFloat64Uint64V(*v, e)
+	case map[float64]uintptr:
+		fastpathTV.EncMapFloat64UintptrV(v, e)
+	case *map[float64]uintptr:
+		fastpathTV.EncMapFloat64UintptrV(*v, e)
+	case map[float64]int:
+		fastpathTV.EncMapFloat64IntV(v, e)
+	case *map[float64]int:
+		fastpathTV.EncMapFloat64IntV(*v, e)
+	case map[float64]int8:
+		fastpathTV.EncMapFloat64Int8V(v, e)
+	case *map[float64]int8:
+		fastpathTV.EncMapFloat64Int8V(*v, e)
+	case map[float64]int16:
+		fastpathTV.EncMapFloat64Int16V(v, e)
+	case *map[float64]int16:
+		fastpathTV.EncMapFloat64Int16V(*v, e)
+	case map[float64]int32:
+		fastpathTV.EncMapFloat64Int32V(v, e)
+	case *map[float64]int32:
+		fastpathTV.EncMapFloat64Int32V(*v, e)
+	case map[float64]int64:
+		fastpathTV.EncMapFloat64Int64V(v, e)
+	case *map[float64]int64:
+		fastpathTV.EncMapFloat64Int64V(*v, e)
+	case map[float64]float32:
+		fastpathTV.EncMapFloat64Float32V(v, e)
+	case *map[float64]float32:
+		fastpathTV.EncMapFloat64Float32V(*v, e)
+	case map[float64]float64:
+		fastpathTV.EncMapFloat64Float64V(v, e)
+	case *map[float64]float64:
+		fastpathTV.EncMapFloat64Float64V(*v, e)
+	case map[float64]bool:
+		fastpathTV.EncMapFloat64BoolV(v, e)
+	case *map[float64]bool:
+		fastpathTV.EncMapFloat64BoolV(*v, e)
+	case map[uint]interface{}:
+		fastpathTV.EncMapUintIntfV(v, e)
+	case *map[uint]interface{}:
+		fastpathTV.EncMapUintIntfV(*v, e)
+	case map[uint]string:
+		fastpathTV.EncMapUintStringV(v, e)
+	case *map[uint]string:
+		fastpathTV.EncMapUintStringV(*v, e)
+	case map[uint]uint:
+		fastpathTV.EncMapUintUintV(v, e)
+	case *map[uint]uint:
+		fastpathTV.EncMapUintUintV(*v, e)
+	case map[uint]uint8:
+		fastpathTV.EncMapUintUint8V(v, e)
+	case *map[uint]uint8:
+		fastpathTV.EncMapUintUint8V(*v, e)
+	case map[uint]uint16:
+		fastpathTV.EncMapUintUint16V(v, e)
+	case *map[uint]uint16:
+		fastpathTV.EncMapUintUint16V(*v, e)
+	case map[uint]uint32:
+		fastpathTV.EncMapUintUint32V(v, e)
+	case *map[uint]uint32:
+		fastpathTV.EncMapUintUint32V(*v, e)
+	case map[uint]uint64:
+		fastpathTV.EncMapUintUint64V(v, e)
+	case *map[uint]uint64:
+		fastpathTV.EncMapUintUint64V(*v, e)
+	case map[uint]uintptr:
+		fastpathTV.EncMapUintUintptrV(v, e)
+	case *map[uint]uintptr:
+		fastpathTV.EncMapUintUintptrV(*v, e)
+	case map[uint]int:
+		fastpathTV.EncMapUintIntV(v, e)
+	case *map[uint]int:
+		fastpathTV.EncMapUintIntV(*v, e)
+	case map[uint]int8:
+		fastpathTV.EncMapUintInt8V(v, e)
+	case *map[uint]int8:
+		fastpathTV.EncMapUintInt8V(*v, e)
+	case map[uint]int16:
+		fastpathTV.EncMapUintInt16V(v, e)
+	case *map[uint]int16:
+		fastpathTV.EncMapUintInt16V(*v, e)
+	case map[uint]int32:
+		fastpathTV.EncMapUintInt32V(v, e)
+	case *map[uint]int32:
+		fastpathTV.EncMapUintInt32V(*v, e)
+	case map[uint]int64:
+		fastpathTV.EncMapUintInt64V(v, e)
+	case *map[uint]int64:
+		fastpathTV.EncMapUintInt64V(*v, e)
+	case map[uint]float32:
+		fastpathTV.EncMapUintFloat32V(v, e)
+	case *map[uint]float32:
+		fastpathTV.EncMapUintFloat32V(*v, e)
+	case map[uint]float64:
+		fastpathTV.EncMapUintFloat64V(v, e)
+	case *map[uint]float64:
+		fastpathTV.EncMapUintFloat64V(*v, e)
+	case map[uint]bool:
+		fastpathTV.EncMapUintBoolV(v, e)
+	case *map[uint]bool:
+		fastpathTV.EncMapUintBoolV(*v, e)
+	case map[uint8]interface{}:
+		fastpathTV.EncMapUint8IntfV(v, e)
+	case *map[uint8]interface{}:
+		fastpathTV.EncMapUint8IntfV(*v, e)
+	case map[uint8]string:
+		fastpathTV.EncMapUint8StringV(v, e)
+	case *map[uint8]string:
+		fastpathTV.EncMapUint8StringV(*v, e)
+	case map[uint8]uint:
+		fastpathTV.EncMapUint8UintV(v, e)
+	case *map[uint8]uint:
+		fastpathTV.EncMapUint8UintV(*v, e)
+	case map[uint8]uint8:
+		fastpathTV.EncMapUint8Uint8V(v, e)
+	case *map[uint8]uint8:
+		fastpathTV.EncMapUint8Uint8V(*v, e)
+	case map[uint8]uint16:
+		fastpathTV.EncMapUint8Uint16V(v, e)
+	case *map[uint8]uint16:
+		fastpathTV.EncMapUint8Uint16V(*v, e)
+	case map[uint8]uint32:
+		fastpathTV.EncMapUint8Uint32V(v, e)
+	case *map[uint8]uint32:
+		fastpathTV.EncMapUint8Uint32V(*v, e)
+	case map[uint8]uint64:
+		fastpathTV.EncMapUint8Uint64V(v, e)
+	case *map[uint8]uint64:
+		fastpathTV.EncMapUint8Uint64V(*v, e)
+	case map[uint8]uintptr:
+		fastpathTV.EncMapUint8UintptrV(v, e)
+	case *map[uint8]uintptr:
+		fastpathTV.EncMapUint8UintptrV(*v, e)
+	case map[uint8]int:
+		fastpathTV.EncMapUint8IntV(v, e)
+	case *map[uint8]int:
+		fastpathTV.EncMapUint8IntV(*v, e)
+	case map[uint8]int8:
+		fastpathTV.EncMapUint8Int8V(v, e)
+	case *map[uint8]int8:
+		fastpathTV.EncMapUint8Int8V(*v, e)
+	case map[uint8]int16:
+		fastpathTV.EncMapUint8Int16V(v, e)
+	case *map[uint8]int16:
+		fastpathTV.EncMapUint8Int16V(*v, e)
+	case map[uint8]int32:
+		fastpathTV.EncMapUint8Int32V(v, e)
+	case *map[uint8]int32:
+		fastpathTV.EncMapUint8Int32V(*v, e)
+	case map[uint8]int64:
+		fastpathTV.EncMapUint8Int64V(v, e)
+	case *map[uint8]int64:
+		fastpathTV.EncMapUint8Int64V(*v, e)
+	case map[uint8]float32:
+		fastpathTV.EncMapUint8Float32V(v, e)
+	case *map[uint8]float32:
+		fastpathTV.EncMapUint8Float32V(*v, e)
+	case map[uint8]float64:
+		fastpathTV.EncMapUint8Float64V(v, e)
+	case *map[uint8]float64:
+		fastpathTV.EncMapUint8Float64V(*v, e)
+	case map[uint8]bool:
+		fastpathTV.EncMapUint8BoolV(v, e)
+	case *map[uint8]bool:
+		fastpathTV.EncMapUint8BoolV(*v, e)
+	case map[uint16]interface{}:
+		fastpathTV.EncMapUint16IntfV(v, e)
+	case *map[uint16]interface{}:
+		fastpathTV.EncMapUint16IntfV(*v, e)
+	case map[uint16]string:
+		fastpathTV.EncMapUint16StringV(v, e)
+	case *map[uint16]string:
+		fastpathTV.EncMapUint16StringV(*v, e)
+	case map[uint16]uint:
+		fastpathTV.EncMapUint16UintV(v, e)
+	case *map[uint16]uint:
+		fastpathTV.EncMapUint16UintV(*v, e)
+	case map[uint16]uint8:
+		fastpathTV.EncMapUint16Uint8V(v, e)
+	case *map[uint16]uint8:
+		fastpathTV.EncMapUint16Uint8V(*v, e)
+	case map[uint16]uint16:
+		fastpathTV.EncMapUint16Uint16V(v, e)
+	case *map[uint16]uint16:
+		fastpathTV.EncMapUint16Uint16V(*v, e)
+	case map[uint16]uint32:
+		fastpathTV.EncMapUint16Uint32V(v, e)
+	case *map[uint16]uint32:
+		fastpathTV.EncMapUint16Uint32V(*v, e)
+	case map[uint16]uint64:
+		fastpathTV.EncMapUint16Uint64V(v, e)
+	case *map[uint16]uint64:
+		fastpathTV.EncMapUint16Uint64V(*v, e)
+	case map[uint16]uintptr:
+		fastpathTV.EncMapUint16UintptrV(v, e)
+	case *map[uint16]uintptr:
+		fastpathTV.EncMapUint16UintptrV(*v, e)
+	case map[uint16]int:
+		fastpathTV.EncMapUint16IntV(v, e)
+	case *map[uint16]int:
+		fastpathTV.EncMapUint16IntV(*v, e)
+	case map[uint16]int8:
+		fastpathTV.EncMapUint16Int8V(v, e)
+	case *map[uint16]int8:
+		fastpathTV.EncMapUint16Int8V(*v, e)
+	case map[uint16]int16:
+		fastpathTV.EncMapUint16Int16V(v, e)
+	case *map[uint16]int16:
+		fastpathTV.EncMapUint16Int16V(*v, e)
+	case map[uint16]int32:
+		fastpathTV.EncMapUint16Int32V(v, e)
+	case *map[uint16]int32:
+		fastpathTV.EncMapUint16Int32V(*v, e)
+	case map[uint16]int64:
+		fastpathTV.EncMapUint16Int64V(v, e)
+	case *map[uint16]int64:
+		fastpathTV.EncMapUint16Int64V(*v, e)
+	case map[uint16]float32:
+		fastpathTV.EncMapUint16Float32V(v, e)
+	case *map[uint16]float32:
+		fastpathTV.EncMapUint16Float32V(*v, e)
+	case map[uint16]float64:
+		fastpathTV.EncMapUint16Float64V(v, e)
+	case *map[uint16]float64:
+		fastpathTV.EncMapUint16Float64V(*v, e)
+	case map[uint16]bool:
+		fastpathTV.EncMapUint16BoolV(v, e)
+	case *map[uint16]bool:
+		fastpathTV.EncMapUint16BoolV(*v, e)
+	case map[uint32]interface{}:
+		fastpathTV.EncMapUint32IntfV(v, e)
+	case *map[uint32]interface{}:
+		fastpathTV.EncMapUint32IntfV(*v, e)
+	case map[uint32]string:
+		fastpathTV.EncMapUint32StringV(v, e)
+	case *map[uint32]string:
+		fastpathTV.EncMapUint32StringV(*v, e)
+	case map[uint32]uint:
+		fastpathTV.EncMapUint32UintV(v, e)
+	case *map[uint32]uint:
+		fastpathTV.EncMapUint32UintV(*v, e)
+	case map[uint32]uint8:
+		fastpathTV.EncMapUint32Uint8V(v, e)
+	case *map[uint32]uint8:
+		fastpathTV.EncMapUint32Uint8V(*v, e)
+	case map[uint32]uint16:
+		fastpathTV.EncMapUint32Uint16V(v, e)
+	case *map[uint32]uint16:
+		fastpathTV.EncMapUint32Uint16V(*v, e)
+	case map[uint32]uint32:
+		fastpathTV.EncMapUint32Uint32V(v, e)
+	case *map[uint32]uint32:
+		fastpathTV.EncMapUint32Uint32V(*v, e)
+	case map[uint32]uint64:
+		fastpathTV.EncMapUint32Uint64V(v, e)
+	case *map[uint32]uint64:
+		fastpathTV.EncMapUint32Uint64V(*v, e)
+	case map[uint32]uintptr:
+		fastpathTV.EncMapUint32UintptrV(v, e)
+	case *map[uint32]uintptr:
+		fastpathTV.EncMapUint32UintptrV(*v, e)
+	case map[uint32]int:
+		fastpathTV.EncMapUint32IntV(v, e)
+	case *map[uint32]int:
+		fastpathTV.EncMapUint32IntV(*v, e)
+	case map[uint32]int8:
+		fastpathTV.EncMapUint32Int8V(v, e)
+	case *map[uint32]int8:
+		fastpathTV.EncMapUint32Int8V(*v, e)
+	case map[uint32]int16:
+		fastpathTV.EncMapUint32Int16V(v, e)
+	case *map[uint32]int16:
+		fastpathTV.EncMapUint32Int16V(*v, e)
+	case map[uint32]int32:
+		fastpathTV.EncMapUint32Int32V(v, e)
+	case *map[uint32]int32:
+		fastpathTV.EncMapUint32Int32V(*v, e)
+	case map[uint32]int64:
+		fastpathTV.EncMapUint32Int64V(v, e)
+	case *map[uint32]int64:
+		fastpathTV.EncMapUint32Int64V(*v, e)
+	case map[uint32]float32:
+		fastpathTV.EncMapUint32Float32V(v, e)
+	case *map[uint32]float32:
+		fastpathTV.EncMapUint32Float32V(*v, e)
+	case map[uint32]float64:
+		fastpathTV.EncMapUint32Float64V(v, e)
+	case *map[uint32]float64:
+		fastpathTV.EncMapUint32Float64V(*v, e)
+	case map[uint32]bool:
+		fastpathTV.EncMapUint32BoolV(v, e)
+	case *map[uint32]bool:
+		fastpathTV.EncMapUint32BoolV(*v, e)
+	case map[uint64]interface{}:
+		fastpathTV.EncMapUint64IntfV(v, e)
+	case *map[uint64]interface{}:
+		fastpathTV.EncMapUint64IntfV(*v, e)
+	case map[uint64]string:
+		fastpathTV.EncMapUint64StringV(v, e)
+	case *map[uint64]string:
+		fastpathTV.EncMapUint64StringV(*v, e)
+	case map[uint64]uint:
+		fastpathTV.EncMapUint64UintV(v, e)
+	case *map[uint64]uint:
+		fastpathTV.EncMapUint64UintV(*v, e)
+	case map[uint64]uint8:
+		fastpathTV.EncMapUint64Uint8V(v, e)
+	case *map[uint64]uint8:
+		fastpathTV.EncMapUint64Uint8V(*v, e)
+	case map[uint64]uint16:
+		fastpathTV.EncMapUint64Uint16V(v, e)
+	case *map[uint64]uint16:
+		fastpathTV.EncMapUint64Uint16V(*v, e)
+	case map[uint64]uint32:
+		fastpathTV.EncMapUint64Uint32V(v, e)
+	case *map[uint64]uint32:
+		fastpathTV.EncMapUint64Uint32V(*v, e)
+	case map[uint64]uint64:
+		fastpathTV.EncMapUint64Uint64V(v, e)
+	case *map[uint64]uint64:
+		fastpathTV.EncMapUint64Uint64V(*v, e)
+	case map[uint64]uintptr:
+		fastpathTV.EncMapUint64UintptrV(v, e)
+	case *map[uint64]uintptr:
+		fastpathTV.EncMapUint64UintptrV(*v, e)
+	case map[uint64]int:
+		fastpathTV.EncMapUint64IntV(v, e)
+	case *map[uint64]int:
+		fastpathTV.EncMapUint64IntV(*v, e)
+	case map[uint64]int8:
+		fastpathTV.EncMapUint64Int8V(v, e)
+	case *map[uint64]int8:
+		fastpathTV.EncMapUint64Int8V(*v, e)
+	case map[uint64]int16:
+		fastpathTV.EncMapUint64Int16V(v, e)
+	case *map[uint64]int16:
+		fastpathTV.EncMapUint64Int16V(*v, e)
+	case map[uint64]int32:
+		fastpathTV.EncMapUint64Int32V(v, e)
+	case *map[uint64]int32:
+		fastpathTV.EncMapUint64Int32V(*v, e)
+	case map[uint64]int64:
+		fastpathTV.EncMapUint64Int64V(v, e)
+	case *map[uint64]int64:
+		fastpathTV.EncMapUint64Int64V(*v, e)
+	case map[uint64]float32:
+		fastpathTV.EncMapUint64Float32V(v, e)
+	case *map[uint64]float32:
+		fastpathTV.EncMapUint64Float32V(*v, e)
+	case map[uint64]float64:
+		fastpathTV.EncMapUint64Float64V(v, e)
+	case *map[uint64]float64:
+		fastpathTV.EncMapUint64Float64V(*v, e)
+	case map[uint64]bool:
+		fastpathTV.EncMapUint64BoolV(v, e)
+	case *map[uint64]bool:
+		fastpathTV.EncMapUint64BoolV(*v, e)
+	case map[uintptr]interface{}:
+		fastpathTV.EncMapUintptrIntfV(v, e)
+	case *map[uintptr]interface{}:
+		fastpathTV.EncMapUintptrIntfV(*v, e)
+	case map[uintptr]string:
+		fastpathTV.EncMapUintptrStringV(v, e)
+	case *map[uintptr]string:
+		fastpathTV.EncMapUintptrStringV(*v, e)
+	case map[uintptr]uint:
+		fastpathTV.EncMapUintptrUintV(v, e)
+	case *map[uintptr]uint:
+		fastpathTV.EncMapUintptrUintV(*v, e)
+	case map[uintptr]uint8:
+		fastpathTV.EncMapUintptrUint8V(v, e)
+	case *map[uintptr]uint8:
+		fastpathTV.EncMapUintptrUint8V(*v, e)
+	case map[uintptr]uint16:
+		fastpathTV.EncMapUintptrUint16V(v, e)
+	case *map[uintptr]uint16:
+		fastpathTV.EncMapUintptrUint16V(*v, e)
+	case map[uintptr]uint32:
+		fastpathTV.EncMapUintptrUint32V(v, e)
+	case *map[uintptr]uint32:
+		fastpathTV.EncMapUintptrUint32V(*v, e)
+	case map[uintptr]uint64:
+		fastpathTV.EncMapUintptrUint64V(v, e)
+	case *map[uintptr]uint64:
+		fastpathTV.EncMapUintptrUint64V(*v, e)
+	case map[uintptr]uintptr:
+		fastpathTV.EncMapUintptrUintptrV(v, e)
+	case *map[uintptr]uintptr:
+		fastpathTV.EncMapUintptrUintptrV(*v, e)
+	case map[uintptr]int:
+		fastpathTV.EncMapUintptrIntV(v, e)
+	case *map[uintptr]int:
+		fastpathTV.EncMapUintptrIntV(*v, e)
+	case map[uintptr]int8:
+		fastpathTV.EncMapUintptrInt8V(v, e)
+	case *map[uintptr]int8:
+		fastpathTV.EncMapUintptrInt8V(*v, e)
+	case map[uintptr]int16:
+		fastpathTV.EncMapUintptrInt16V(v, e)
+	case *map[uintptr]int16:
+		fastpathTV.EncMapUintptrInt16V(*v, e)
+	case map[uintptr]int32:
+		fastpathTV.EncMapUintptrInt32V(v, e)
+	case *map[uintptr]int32:
+		fastpathTV.EncMapUintptrInt32V(*v, e)
+	case map[uintptr]int64:
+		fastpathTV.EncMapUintptrInt64V(v, e)
+	case *map[uintptr]int64:
+		fastpathTV.EncMapUintptrInt64V(*v, e)
+	case map[uintptr]float32:
+		fastpathTV.EncMapUintptrFloat32V(v, e)
+	case *map[uintptr]float32:
+		fastpathTV.EncMapUintptrFloat32V(*v, e)
+	case map[uintptr]float64:
+		fastpathTV.EncMapUintptrFloat64V(v, e)
+	case *map[uintptr]float64:
+		fastpathTV.EncMapUintptrFloat64V(*v, e)
+	case map[uintptr]bool:
+		fastpathTV.EncMapUintptrBoolV(v, e)
+	case *map[uintptr]bool:
+		fastpathTV.EncMapUintptrBoolV(*v, e)
+	case map[int]interface{}:
+		fastpathTV.EncMapIntIntfV(v, e)
+	case *map[int]interface{}:
+		fastpathTV.EncMapIntIntfV(*v, e)
+	case map[int]string:
+		fastpathTV.EncMapIntStringV(v, e)
+	case *map[int]string:
+		fastpathTV.EncMapIntStringV(*v, e)
+	case map[int]uint:
+		fastpathTV.EncMapIntUintV(v, e)
+	case *map[int]uint:
+		fastpathTV.EncMapIntUintV(*v, e)
+	case map[int]uint8:
+		fastpathTV.EncMapIntUint8V(v, e)
+	case *map[int]uint8:
+		fastpathTV.EncMapIntUint8V(*v, e)
+	case map[int]uint16:
+		fastpathTV.EncMapIntUint16V(v, e)
+	case *map[int]uint16:
+		fastpathTV.EncMapIntUint16V(*v, e)
+	case map[int]uint32:
+		fastpathTV.EncMapIntUint32V(v, e)
+	case *map[int]uint32:
+		fastpathTV.EncMapIntUint32V(*v, e)
+	case map[int]uint64:
+		fastpathTV.EncMapIntUint64V(v, e)
+	case *map[int]uint64:
+		fastpathTV.EncMapIntUint64V(*v, e)
+	case map[int]uintptr:
+		fastpathTV.EncMapIntUintptrV(v, e)
+	case *map[int]uintptr:
+		fastpathTV.EncMapIntUintptrV(*v, e)
+	case map[int]int:
+		fastpathTV.EncMapIntIntV(v, e)
+	case *map[int]int:
+		fastpathTV.EncMapIntIntV(*v, e)
+	case map[int]int8:
+		fastpathTV.EncMapIntInt8V(v, e)
+	case *map[int]int8:
+		fastpathTV.EncMapIntInt8V(*v, e)
+	case map[int]int16:
+		fastpathTV.EncMapIntInt16V(v, e)
+	case *map[int]int16:
+		fastpathTV.EncMapIntInt16V(*v, e)
+	case map[int]int32:
+		fastpathTV.EncMapIntInt32V(v, e)
+	case *map[int]int32:
+		fastpathTV.EncMapIntInt32V(*v, e)
+	case map[int]int64:
+		fastpathTV.EncMapIntInt64V(v, e)
+	case *map[int]int64:
+		fastpathTV.EncMapIntInt64V(*v, e)
+	case map[int]float32:
+		fastpathTV.EncMapIntFloat32V(v, e)
+	case *map[int]float32:
+		fastpathTV.EncMapIntFloat32V(*v, e)
+	case map[int]float64:
+		fastpathTV.EncMapIntFloat64V(v, e)
+	case *map[int]float64:
+		fastpathTV.EncMapIntFloat64V(*v, e)
+	case map[int]bool:
+		fastpathTV.EncMapIntBoolV(v, e)
+	case *map[int]bool:
+		fastpathTV.EncMapIntBoolV(*v, e)
+	case map[int8]interface{}:
+		fastpathTV.EncMapInt8IntfV(v, e)
+	case *map[int8]interface{}:
+		fastpathTV.EncMapInt8IntfV(*v, e)
+	case map[int8]string:
+		fastpathTV.EncMapInt8StringV(v, e)
+	case *map[int8]string:
+		fastpathTV.EncMapInt8StringV(*v, e)
+	case map[int8]uint:
+		fastpathTV.EncMapInt8UintV(v, e)
+	case *map[int8]uint:
+		fastpathTV.EncMapInt8UintV(*v, e)
+	case map[int8]uint8:
+		fastpathTV.EncMapInt8Uint8V(v, e)
+	case *map[int8]uint8:
+		fastpathTV.EncMapInt8Uint8V(*v, e)
+	case map[int8]uint16:
+		fastpathTV.EncMapInt8Uint16V(v, e)
+	case *map[int8]uint16:
+		fastpathTV.EncMapInt8Uint16V(*v, e)
+	case map[int8]uint32:
+		fastpathTV.EncMapInt8Uint32V(v, e)
+	case *map[int8]uint32:
+		fastpathTV.EncMapInt8Uint32V(*v, e)
+	case map[int8]uint64:
+		fastpathTV.EncMapInt8Uint64V(v, e)
+	case *map[int8]uint64:
+		fastpathTV.EncMapInt8Uint64V(*v, e)
+	case map[int8]uintptr:
+		fastpathTV.EncMapInt8UintptrV(v, e)
+	case *map[int8]uintptr:
+		fastpathTV.EncMapInt8UintptrV(*v, e)
+	case map[int8]int:
+		fastpathTV.EncMapInt8IntV(v, e)
+	case *map[int8]int:
+		fastpathTV.EncMapInt8IntV(*v, e)
+	case map[int8]int8:
+		fastpathTV.EncMapInt8Int8V(v, e)
+	case *map[int8]int8:
+		fastpathTV.EncMapInt8Int8V(*v, e)
+	case map[int8]int16:
+		fastpathTV.EncMapInt8Int16V(v, e)
+	case *map[int8]int16:
+		fastpathTV.EncMapInt8Int16V(*v, e)
+	case map[int8]int32:
+		fastpathTV.EncMapInt8Int32V(v, e)
+	case *map[int8]int32:
+		fastpathTV.EncMapInt8Int32V(*v, e)
+	case map[int8]int64:
+		fastpathTV.EncMapInt8Int64V(v, e)
+	case *map[int8]int64:
+		fastpathTV.EncMapInt8Int64V(*v, e)
+	case map[int8]float32:
+		fastpathTV.EncMapInt8Float32V(v, e)
+	case *map[int8]float32:
+		fastpathTV.EncMapInt8Float32V(*v, e)
+	case map[int8]float64:
+		fastpathTV.EncMapInt8Float64V(v, e)
+	case *map[int8]float64:
+		fastpathTV.EncMapInt8Float64V(*v, e)
+	case map[int8]bool:
+		fastpathTV.EncMapInt8BoolV(v, e)
+	case *map[int8]bool:
+		fastpathTV.EncMapInt8BoolV(*v, e)
+	case map[int16]interface{}:
+		fastpathTV.EncMapInt16IntfV(v, e)
+	case *map[int16]interface{}:
+		fastpathTV.EncMapInt16IntfV(*v, e)
+	case map[int16]string:
+		fastpathTV.EncMapInt16StringV(v, e)
+	case *map[int16]string:
+		fastpathTV.EncMapInt16StringV(*v, e)
+	case map[int16]uint:
+		fastpathTV.EncMapInt16UintV(v, e)
+	case *map[int16]uint:
+		fastpathTV.EncMapInt16UintV(*v, e)
+	case map[int16]uint8:
+		fastpathTV.EncMapInt16Uint8V(v, e)
+	case *map[int16]uint8:
+		fastpathTV.EncMapInt16Uint8V(*v, e)
+	case map[int16]uint16:
+		fastpathTV.EncMapInt16Uint16V(v, e)
+	case *map[int16]uint16:
+		fastpathTV.EncMapInt16Uint16V(*v, e)
+	case map[int16]uint32:
+		fastpathTV.EncMapInt16Uint32V(v, e)
+	case *map[int16]uint32:
+		fastpathTV.EncMapInt16Uint32V(*v, e)
+	case map[int16]uint64:
+		fastpathTV.EncMapInt16Uint64V(v, e)
+	case *map[int16]uint64:
+		fastpathTV.EncMapInt16Uint64V(*v, e)
+	case map[int16]uintptr:
+		fastpathTV.EncMapInt16UintptrV(v, e)
+	case *map[int16]uintptr:
+		fastpathTV.EncMapInt16UintptrV(*v, e)
+	case map[int16]int:
+		fastpathTV.EncMapInt16IntV(v, e)
+	case *map[int16]int:
+		fastpathTV.EncMapInt16IntV(*v, e)
+	case map[int16]int8:
+		fastpathTV.EncMapInt16Int8V(v, e)
+	case *map[int16]int8:
+		fastpathTV.EncMapInt16Int8V(*v, e)
+	case map[int16]int16:
+		fastpathTV.EncMapInt16Int16V(v, e)
+	case *map[int16]int16:
+		fastpathTV.EncMapInt16Int16V(*v, e)
+	case map[int16]int32:
+		fastpathTV.EncMapInt16Int32V(v, e)
+	case *map[int16]int32:
+		fastpathTV.EncMapInt16Int32V(*v, e)
+	case map[int16]int64:
+		fastpathTV.EncMapInt16Int64V(v, e)
+	case *map[int16]int64:
+		fastpathTV.EncMapInt16Int64V(*v, e)
+	case map[int16]float32:
+		fastpathTV.EncMapInt16Float32V(v, e)
+	case *map[int16]float32:
+		fastpathTV.EncMapInt16Float32V(*v, e)
+	case map[int16]float64:
+		fastpathTV.EncMapInt16Float64V(v, e)
+	case *map[int16]float64:
+		fastpathTV.EncMapInt16Float64V(*v, e)
+	case map[int16]bool:
+		fastpathTV.EncMapInt16BoolV(v, e)
+	case *map[int16]bool:
+		fastpathTV.EncMapInt16BoolV(*v, e)
+	case map[int32]interface{}:
+		fastpathTV.EncMapInt32IntfV(v, e)
+	case *map[int32]interface{}:
+		fastpathTV.EncMapInt32IntfV(*v, e)
+	case map[int32]string:
+		fastpathTV.EncMapInt32StringV(v, e)
+	case *map[int32]string:
+		fastpathTV.EncMapInt32StringV(*v, e)
+	case map[int32]uint:
+		fastpathTV.EncMapInt32UintV(v, e)
+	case *map[int32]uint:
+		fastpathTV.EncMapInt32UintV(*v, e)
+	case map[int32]uint8:
+		fastpathTV.EncMapInt32Uint8V(v, e)
+	case *map[int32]uint8:
+		fastpathTV.EncMapInt32Uint8V(*v, e)
+	case map[int32]uint16:
+		fastpathTV.EncMapInt32Uint16V(v, e)
+	case *map[int32]uint16:
+		fastpathTV.EncMapInt32Uint16V(*v, e)
+	case map[int32]uint32:
+		fastpathTV.EncMapInt32Uint32V(v, e)
+	case *map[int32]uint32:
+		fastpathTV.EncMapInt32Uint32V(*v, e)
+	case map[int32]uint64:
+		fastpathTV.EncMapInt32Uint64V(v, e)
+	case *map[int32]uint64:
+		fastpathTV.EncMapInt32Uint64V(*v, e)
+	case map[int32]uintptr:
+		fastpathTV.EncMapInt32UintptrV(v, e)
+	case *map[int32]uintptr:
+		fastpathTV.EncMapInt32UintptrV(*v, e)
+	case map[int32]int:
+		fastpathTV.EncMapInt32IntV(v, e)
+	case *map[int32]int:
+		fastpathTV.EncMapInt32IntV(*v, e)
+	case map[int32]int8:
+		fastpathTV.EncMapInt32Int8V(v, e)
+	case *map[int32]int8:
+		fastpathTV.EncMapInt32Int8V(*v, e)
+	case map[int32]int16:
+		fastpathTV.EncMapInt32Int16V(v, e)
+	case *map[int32]int16:
+		fastpathTV.EncMapInt32Int16V(*v, e)
+	case map[int32]int32:
+		fastpathTV.EncMapInt32Int32V(v, e)
+	case *map[int32]int32:
+		fastpathTV.EncMapInt32Int32V(*v, e)
+	case map[int32]int64:
+		fastpathTV.EncMapInt32Int64V(v, e)
+	case *map[int32]int64:
+		fastpathTV.EncMapInt32Int64V(*v, e)
+	case map[int32]float32:
+		fastpathTV.EncMapInt32Float32V(v, e)
+	case *map[int32]float32:
+		fastpathTV.EncMapInt32Float32V(*v, e)
+	case map[int32]float64:
+		fastpathTV.EncMapInt32Float64V(v, e)
+	case *map[int32]float64:
+		fastpathTV.EncMapInt32Float64V(*v, e)
+	case map[int32]bool:
+		fastpathTV.EncMapInt32BoolV(v, e)
+	case *map[int32]bool:
+		fastpathTV.EncMapInt32BoolV(*v, e)
+	case map[int64]interface{}:
+		fastpathTV.EncMapInt64IntfV(v, e)
+	case *map[int64]interface{}:
+		fastpathTV.EncMapInt64IntfV(*v, e)
+	case map[int64]string:
+		fastpathTV.EncMapInt64StringV(v, e)
+	case *map[int64]string:
+		fastpathTV.EncMapInt64StringV(*v, e)
+	case map[int64]uint:
+		fastpathTV.EncMapInt64UintV(v, e)
+	case *map[int64]uint:
+		fastpathTV.EncMapInt64UintV(*v, e)
+	case map[int64]uint8:
+		fastpathTV.EncMapInt64Uint8V(v, e)
+	case *map[int64]uint8:
+		fastpathTV.EncMapInt64Uint8V(*v, e)
+	case map[int64]uint16:
+		fastpathTV.EncMapInt64Uint16V(v, e)
+	case *map[int64]uint16:
+		fastpathTV.EncMapInt64Uint16V(*v, e)
+	case map[int64]uint32:
+		fastpathTV.EncMapInt64Uint32V(v, e)
+	case *map[int64]uint32:
+		fastpathTV.EncMapInt64Uint32V(*v, e)
+	case map[int64]uint64:
+		fastpathTV.EncMapInt64Uint64V(v, e)
+	case *map[int64]uint64:
+		fastpathTV.EncMapInt64Uint64V(*v, e)
+	case map[int64]uintptr:
+		fastpathTV.EncMapInt64UintptrV(v, e)
+	case *map[int64]uintptr:
+		fastpathTV.EncMapInt64UintptrV(*v, e)
+	case map[int64]int:
+		fastpathTV.EncMapInt64IntV(v, e)
+	case *map[int64]int:
+		fastpathTV.EncMapInt64IntV(*v, e)
+	case map[int64]int8:
+		fastpathTV.EncMapInt64Int8V(v, e)
+	case *map[int64]int8:
+		fastpathTV.EncMapInt64Int8V(*v, e)
+	case map[int64]int16:
+		fastpathTV.EncMapInt64Int16V(v, e)
+	case *map[int64]int16:
+		fastpathTV.EncMapInt64Int16V(*v, e)
+	case map[int64]int32:
+		fastpathTV.EncMapInt64Int32V(v, e)
+	case *map[int64]int32:
+		fastpathTV.EncMapInt64Int32V(*v, e)
+	case map[int64]int64:
+		fastpathTV.EncMapInt64Int64V(v, e)
+	case *map[int64]int64:
+		fastpathTV.EncMapInt64Int64V(*v, e)
+	case map[int64]float32:
+		fastpathTV.EncMapInt64Float32V(v, e)
+	case *map[int64]float32:
+		fastpathTV.EncMapInt64Float32V(*v, e)
+	case map[int64]float64:
+		fastpathTV.EncMapInt64Float64V(v, e)
+	case *map[int64]float64:
+		fastpathTV.EncMapInt64Float64V(*v, e)
+	case map[int64]bool:
+		fastpathTV.EncMapInt64BoolV(v, e)
+	case *map[int64]bool:
+		fastpathTV.EncMapInt64BoolV(*v, e)
+	case map[bool]interface{}:
+		fastpathTV.EncMapBoolIntfV(v, e)
+	case *map[bool]interface{}:
+		fastpathTV.EncMapBoolIntfV(*v, e)
+	case map[bool]string:
+		fastpathTV.EncMapBoolStringV(v, e)
+	case *map[bool]string:
+		fastpathTV.EncMapBoolStringV(*v, e)
+	case map[bool]uint:
+		fastpathTV.EncMapBoolUintV(v, e)
+	case *map[bool]uint:
+		fastpathTV.EncMapBoolUintV(*v, e)
+	case map[bool]uint8:
+		fastpathTV.EncMapBoolUint8V(v, e)
+	case *map[bool]uint8:
+		fastpathTV.EncMapBoolUint8V(*v, e)
+	case map[bool]uint16:
+		fastpathTV.EncMapBoolUint16V(v, e)
+	case *map[bool]uint16:
+		fastpathTV.EncMapBoolUint16V(*v, e)
+	case map[bool]uint32:
+		fastpathTV.EncMapBoolUint32V(v, e)
+	case *map[bool]uint32:
+		fastpathTV.EncMapBoolUint32V(*v, e)
+	case map[bool]uint64:
+		fastpathTV.EncMapBoolUint64V(v, e)
+	case *map[bool]uint64:
+		fastpathTV.EncMapBoolUint64V(*v, e)
+	case map[bool]uintptr:
+		fastpathTV.EncMapBoolUintptrV(v, e)
+	case *map[bool]uintptr:
+		fastpathTV.EncMapBoolUintptrV(*v, e)
+	case map[bool]int:
+		fastpathTV.EncMapBoolIntV(v, e)
+	case *map[bool]int:
+		fastpathTV.EncMapBoolIntV(*v, e)
+	case map[bool]int8:
+		fastpathTV.EncMapBoolInt8V(v, e)
+	case *map[bool]int8:
+		fastpathTV.EncMapBoolInt8V(*v, e)
+	case map[bool]int16:
+		fastpathTV.EncMapBoolInt16V(v, e)
+	case *map[bool]int16:
+		fastpathTV.EncMapBoolInt16V(*v, e)
+	case map[bool]int32:
+		fastpathTV.EncMapBoolInt32V(v, e)
+	case *map[bool]int32:
+		fastpathTV.EncMapBoolInt32V(*v, e)
+	case map[bool]int64:
+		fastpathTV.EncMapBoolInt64V(v, e)
+	case *map[bool]int64:
+		fastpathTV.EncMapBoolInt64V(*v, e)
+	case map[bool]float32:
+		fastpathTV.EncMapBoolFloat32V(v, e)
+	case *map[bool]float32:
+		fastpathTV.EncMapBoolFloat32V(*v, e)
+	case map[bool]float64:
+		fastpathTV.EncMapBoolFloat64V(v, e)
+	case *map[bool]float64:
+		fastpathTV.EncMapBoolFloat64V(*v, e)
+	case map[bool]bool:
+		fastpathTV.EncMapBoolBoolV(v, e)
+	case *map[bool]bool:
+		fastpathTV.EncMapBoolBoolV(*v, e)
+
+	default:
+		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+// -- -- fast path functions
+
+func (e *Encoder) fastpathEncSliceIntfR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceIntfV(rv2i(rv).([]interface{}), e)
+	} else {
+		fastpathTV.EncSliceIntfV(rv2i(rv).([]interface{}), e)
+	}
+}
+func (_ fastpathT) EncSliceIntfV(v []interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			e.encode(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			e.encode(v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			e.encode(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			e.encode(v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceStringR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceStringV(rv2i(rv).([]string), e)
+	} else {
+		fastpathTV.EncSliceStringV(rv2i(rv).([]string), e)
+	}
+}
+func (_ fastpathT) EncSliceStringV(v []string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeString(cUTF8, v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeString(cUTF8, v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceStringV(v []string, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeString(cUTF8, v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeString(cUTF8, v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceFloat32V(rv2i(rv).([]float32), e)
+	} else {
+		fastpathTV.EncSliceFloat32V(rv2i(rv).([]float32), e)
+	}
+}
+func (_ fastpathT) EncSliceFloat32V(v []float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeFloat32(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeFloat32(v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeFloat32(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeFloat32(v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceFloat64V(rv2i(rv).([]float64), e)
+	} else {
+		fastpathTV.EncSliceFloat64V(rv2i(rv).([]float64), e)
+	}
+}
+func (_ fastpathT) EncSliceFloat64V(v []float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeFloat64(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeFloat64(v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeFloat64(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeFloat64(v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUintR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUintV(rv2i(rv).([]uint), e)
+	} else {
+		fastpathTV.EncSliceUintV(rv2i(rv).([]uint), e)
+	}
+}
+func (_ fastpathT) EncSliceUintV(v []uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUintV(v []uint, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUint8R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint8V(rv2i(rv).([]uint8), e)
+	} else {
+		fastpathTV.EncSliceUint8V(rv2i(rv).([]uint8), e)
+	}
+}
+func (_ fastpathT) EncSliceUint8V(v []uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUint8V(v []uint8, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUint16R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint16V(rv2i(rv).([]uint16), e)
+	} else {
+		fastpathTV.EncSliceUint16V(rv2i(rv).([]uint16), e)
+	}
+}
+func (_ fastpathT) EncSliceUint16V(v []uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUint32R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint32V(rv2i(rv).([]uint32), e)
+	} else {
+		fastpathTV.EncSliceUint32V(rv2i(rv).([]uint32), e)
+	}
+}
+func (_ fastpathT) EncSliceUint32V(v []uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUint64R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUint64V(rv2i(rv).([]uint64), e)
+	} else {
+		fastpathTV.EncSliceUint64V(rv2i(rv).([]uint64), e)
+	}
+}
+func (_ fastpathT) EncSliceUint64V(v []uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeUint(uint64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeUint(uint64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceUintptrV(rv2i(rv).([]uintptr), e)
+	} else {
+		fastpathTV.EncSliceUintptrV(rv2i(rv).([]uintptr), e)
+	}
+}
+func (_ fastpathT) EncSliceUintptrV(v []uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			e.encode(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			e.encode(v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			e.encode(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			e.encode(v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceIntR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceIntV(rv2i(rv).([]int), e)
+	} else {
+		fastpathTV.EncSliceIntV(rv2i(rv).([]int), e)
+	}
+}
+func (_ fastpathT) EncSliceIntV(v []int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceIntV(v []int, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceInt8R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt8V(rv2i(rv).([]int8), e)
+	} else {
+		fastpathTV.EncSliceInt8V(rv2i(rv).([]int8), e)
+	}
+}
+func (_ fastpathT) EncSliceInt8V(v []int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceInt8V(v []int8, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceInt16R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt16V(rv2i(rv).([]int16), e)
+	} else {
+		fastpathTV.EncSliceInt16V(rv2i(rv).([]int16), e)
+	}
+}
+func (_ fastpathT) EncSliceInt16V(v []int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceInt16V(v []int16, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceInt32R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt32V(rv2i(rv).([]int32), e)
+	} else {
+		fastpathTV.EncSliceInt32V(rv2i(rv).([]int32), e)
+	}
+}
+func (_ fastpathT) EncSliceInt32V(v []int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceInt32V(v []int32, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceInt64R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceInt64V(rv2i(rv).([]int64), e)
+	} else {
+		fastpathTV.EncSliceInt64V(rv2i(rv).([]int64), e)
+	}
+}
+func (_ fastpathT) EncSliceInt64V(v []int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceInt64V(v []int64, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeInt(int64(v2))
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeInt(int64(v2))
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncSliceBoolR(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.EncAsMapSliceBoolV(rv2i(rv).([]bool), e)
+	} else {
+		fastpathTV.EncSliceBoolV(rv2i(rv).([]bool), e)
+	}
+}
+func (_ fastpathT) EncSliceBoolV(v []bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			ee.EncodeBool(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeBool(v2)
+		}
+	}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) EncAsMapSliceBoolV(v []bool, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			ee.EncodeBool(v2)
+		}
+	} else {
+		for _, v2 := range v {
+			ee.EncodeBool(v2)
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), e)
+}
+func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfStringV(rv2i(rv).(map[interface{}]string), e)
+}
+func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUintV(rv2i(rv).(map[interface{}]uint), e)
+}
+func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), e)
+}
+func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), e)
+}
+func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), e)
+}
+func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), e)
+}
+func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), e)
+}
+func (_ fastpathT) EncMapIntfUintptrV(v map[interface{}]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfIntV(rv2i(rv).(map[interface{}]int), e)
+}
+func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfInt8V(rv2i(rv).(map[interface{}]int8), e)
+}
+func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfInt16V(rv2i(rv).(map[interface{}]int16), e)
+}
+func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfInt32V(rv2i(rv).(map[interface{}]int32), e)
+}
+func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfInt64V(rv2i(rv).(map[interface{}]int64), e)
+}
+func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), e)
+}
+func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), e)
+}
+func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntfBoolV(rv2i(rv).(map[interface{}]bool), e)
+}
+func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringIntfV(rv2i(rv).(map[string]interface{}), e)
+}
+func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				e.encode(v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				e.encode(v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringStringV(rv2i(rv).(map[string]string), e)
+}
+func (_ fastpathT) EncMapStringStringV(v map[string]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeString(cUTF8, v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUintV(rv2i(rv).(map[string]uint), e)
+}
+func (_ fastpathT) EncMapStringUintV(v map[string]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUint8V(rv2i(rv).(map[string]uint8), e)
+}
+func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUint16V(rv2i(rv).(map[string]uint16), e)
+}
+func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUint32V(rv2i(rv).(map[string]uint32), e)
+}
+func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUint64V(rv2i(rv).(map[string]uint64), e)
+}
+func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringUintptrV(rv2i(rv).(map[string]uintptr), e)
+}
+func (_ fastpathT) EncMapStringUintptrV(v map[string]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				e.encode(v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				e.encode(v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringIntV(rv2i(rv).(map[string]int), e)
+}
+func (_ fastpathT) EncMapStringIntV(v map[string]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringInt8V(rv2i(rv).(map[string]int8), e)
+}
+func (_ fastpathT) EncMapStringInt8V(v map[string]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringInt16V(rv2i(rv).(map[string]int16), e)
+}
+func (_ fastpathT) EncMapStringInt16V(v map[string]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringInt32V(rv2i(rv).(map[string]int32), e)
+}
+func (_ fastpathT) EncMapStringInt32V(v map[string]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringInt64V(rv2i(rv).(map[string]int64), e)
+}
+func (_ fastpathT) EncMapStringInt64V(v map[string]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v[string(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringFloat32V(rv2i(rv).(map[string]float32), e)
+}
+func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeFloat32(v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringFloat64V(rv2i(rv).(map[string]float64), e)
+}
+func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeFloat64(v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapStringBoolV(rv2i(rv).(map[string]bool), e)
+}
+func (_ fastpathT) EncMapStringBoolV(v map[string]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]string, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = string(k)
+			i++
+		}
+		sort.Sort(stringSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[string(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeBool(v[string(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeString(cUTF8, k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeString(cUTF8, k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), e)
+}
+func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				e.encode(v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32StringV(rv2i(rv).(map[float32]string), e)
+}
+func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeString(cUTF8, v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32UintV(rv2i(rv).(map[float32]uint), e)
+}
+func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), e)
+}
+func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), e)
+}
+func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), e)
+}
+func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), e)
+}
+func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeUint(uint64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), e)
+}
+func (_ fastpathT) EncMapFloat32UintptrV(v map[float32]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				e.encode(v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32IntV(rv2i(rv).(map[float32]int), e)
+}
+func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int8V(rv2i(rv).(map[float32]int8), e)
+}
+func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int16V(rv2i(rv).(map[float32]int16), e)
+}
+func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int32V(rv2i(rv).(map[float32]int32), e)
+}
+func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Int64V(rv2i(rv).(map[float32]int64), e)
+}
+func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeInt(int64(v[float32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Float32V(rv2i(rv).(map[float32]float32), e)
+}
+func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeFloat32(v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32Float64V(rv2i(rv).(map[float32]float64), e)
+}
+func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeFloat64(v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat32BoolV(rv2i(rv).(map[float32]bool), e)
+}
+func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(float32(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[float32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat32(float32(k2))
+				ee.EncodeBool(v[float32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat32(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat32(k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), e)
+}
+func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				e.encode(v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64StringV(rv2i(rv).(map[float64]string), e)
+}
+func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeString(cUTF8, v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64UintV(rv2i(rv).(map[float64]uint), e)
+}
+func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), e)
+}
+func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), e)
+}
+func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), e)
+}
+func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), e)
+}
+func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeUint(uint64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), e)
+}
+func (_ fastpathT) EncMapFloat64UintptrV(v map[float64]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				e.encode(v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64IntV(rv2i(rv).(map[float64]int), e)
+}
+func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int8V(rv2i(rv).(map[float64]int8), e)
+}
+func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int16V(rv2i(rv).(map[float64]int16), e)
+}
+func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int32V(rv2i(rv).(map[float64]int32), e)
+}
+func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Int64V(rv2i(rv).(map[float64]int64), e)
+}
+func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeInt(int64(v[float64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Float32V(rv2i(rv).(map[float64]float32), e)
+}
+func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeFloat32(v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64Float64V(rv2i(rv).(map[float64]float64), e)
+}
+func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeFloat64(v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapFloat64BoolV(rv2i(rv).(map[float64]bool), e)
+}
+func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]float64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = float64(k)
+			i++
+		}
+		sort.Sort(floatSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(float64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[float64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeFloat64(float64(k2))
+				ee.EncodeBool(v[float64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeFloat64(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeFloat64(k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintIntfV(rv2i(rv).(map[uint]interface{}), e)
+}
+func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				e.encode(v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintStringV(rv2i(rv).(map[uint]string), e)
+}
+func (_ fastpathT) EncMapUintStringV(v map[uint]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeString(cUTF8, v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUintV(rv2i(rv).(map[uint]uint), e)
+}
+func (_ fastpathT) EncMapUintUintV(v map[uint]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUint8V(rv2i(rv).(map[uint]uint8), e)
+}
+func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUint16V(rv2i(rv).(map[uint]uint16), e)
+}
+func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUint32V(rv2i(rv).(map[uint]uint32), e)
+}
+func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUint64V(rv2i(rv).(map[uint]uint64), e)
+}
+func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeUint(uint64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintUintptrV(rv2i(rv).(map[uint]uintptr), e)
+}
+func (_ fastpathT) EncMapUintUintptrV(v map[uint]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				e.encode(v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintIntV(rv2i(rv).(map[uint]int), e)
+}
+func (_ fastpathT) EncMapUintIntV(v map[uint]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintInt8V(rv2i(rv).(map[uint]int8), e)
+}
+func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintInt16V(rv2i(rv).(map[uint]int16), e)
+}
+func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintInt32V(rv2i(rv).(map[uint]int32), e)
+}
+func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintInt64V(rv2i(rv).(map[uint]int64), e)
+}
+func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeInt(int64(v[uint(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintFloat32V(rv2i(rv).(map[uint]float32), e)
+}
+func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeFloat32(v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintFloat64V(rv2i(rv).(map[uint]float64), e)
+}
+func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeFloat64(v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintBoolV(rv2i(rv).(map[uint]bool), e)
+}
+func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uint(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint(k2)))
+				ee.EncodeBool(v[uint(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), e)
+}
+func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				e.encode(v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8StringV(rv2i(rv).(map[uint8]string), e)
+}
+func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeString(cUTF8, v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8UintV(rv2i(rv).(map[uint8]uint), e)
+}
+func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), e)
+}
+func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), e)
+}
+func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), e)
+}
+func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), e)
+}
+func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeUint(uint64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), e)
+}
+func (_ fastpathT) EncMapUint8UintptrV(v map[uint8]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				e.encode(v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8IntV(rv2i(rv).(map[uint8]int), e)
+}
+func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Int8V(rv2i(rv).(map[uint8]int8), e)
+}
+func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Int16V(rv2i(rv).(map[uint8]int16), e)
+}
+func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Int32V(rv2i(rv).(map[uint8]int32), e)
+}
+func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Int64V(rv2i(rv).(map[uint8]int64), e)
+}
+func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeInt(int64(v[uint8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Float32V(rv2i(rv).(map[uint8]float32), e)
+}
+func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeFloat32(v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8Float64V(rv2i(rv).(map[uint8]float64), e)
+}
+func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeFloat64(v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint8BoolV(rv2i(rv).(map[uint8]bool), e)
+}
+func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uint8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint8(k2)))
+				ee.EncodeBool(v[uint8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), e)
+}
+func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				e.encode(v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16StringV(rv2i(rv).(map[uint16]string), e)
+}
+func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeString(cUTF8, v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16UintV(rv2i(rv).(map[uint16]uint), e)
+}
+func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), e)
+}
+func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), e)
+}
+func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), e)
+}
+func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), e)
+}
+func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeUint(uint64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), e)
+}
+func (_ fastpathT) EncMapUint16UintptrV(v map[uint16]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				e.encode(v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16IntV(rv2i(rv).(map[uint16]int), e)
+}
+func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Int8V(rv2i(rv).(map[uint16]int8), e)
+}
+func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Int16V(rv2i(rv).(map[uint16]int16), e)
+}
+func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Int32V(rv2i(rv).(map[uint16]int32), e)
+}
+func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Int64V(rv2i(rv).(map[uint16]int64), e)
+}
+func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeInt(int64(v[uint16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Float32V(rv2i(rv).(map[uint16]float32), e)
+}
+func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeFloat32(v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16Float64V(rv2i(rv).(map[uint16]float64), e)
+}
+func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeFloat64(v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint16BoolV(rv2i(rv).(map[uint16]bool), e)
+}
+func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uint16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint16(k2)))
+				ee.EncodeBool(v[uint16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), e)
+}
+func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				e.encode(v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32StringV(rv2i(rv).(map[uint32]string), e)
+}
+func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeString(cUTF8, v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32UintV(rv2i(rv).(map[uint32]uint), e)
+}
+func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), e)
+}
+func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), e)
+}
+func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), e)
+}
+func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), e)
+}
+func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeUint(uint64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), e)
+}
+func (_ fastpathT) EncMapUint32UintptrV(v map[uint32]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				e.encode(v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32IntV(rv2i(rv).(map[uint32]int), e)
+}
+func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Int8V(rv2i(rv).(map[uint32]int8), e)
+}
+func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Int16V(rv2i(rv).(map[uint32]int16), e)
+}
+func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Int32V(rv2i(rv).(map[uint32]int32), e)
+}
+func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Int64V(rv2i(rv).(map[uint32]int64), e)
+}
+func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeInt(int64(v[uint32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Float32V(rv2i(rv).(map[uint32]float32), e)
+}
+func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeFloat32(v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32Float64V(rv2i(rv).(map[uint32]float64), e)
+}
+func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeFloat64(v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint32BoolV(rv2i(rv).(map[uint32]bool), e)
+}
+func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uint32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint32(k2)))
+				ee.EncodeBool(v[uint32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), e)
+}
+func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				e.encode(v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64StringV(rv2i(rv).(map[uint64]string), e)
+}
+func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeString(cUTF8, v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64UintV(rv2i(rv).(map[uint64]uint), e)
+}
+func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), e)
+}
+func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), e)
+}
+func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), e)
+}
+func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), e)
+}
+func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeUint(uint64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), e)
+}
+func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				e.encode(v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64IntV(rv2i(rv).(map[uint64]int), e)
+}
+func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Int8V(rv2i(rv).(map[uint64]int8), e)
+}
+func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Int16V(rv2i(rv).(map[uint64]int16), e)
+}
+func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Int32V(rv2i(rv).(map[uint64]int32), e)
+}
+func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Int64V(rv2i(rv).(map[uint64]int64), e)
+}
+func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeInt(int64(v[uint64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Float32V(rv2i(rv).(map[uint64]float32), e)
+}
+func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeFloat32(v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64Float64V(rv2i(rv).(map[uint64]float64), e)
+}
+func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeFloat64(v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUint64BoolV(rv2i(rv).(map[uint64]bool), e)
+}
+func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uint64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeUint(uint64(uint64(k2)))
+				ee.EncodeBool(v[uint64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeUint(uint64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeUint(uint64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), e)
+}
+func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				e.encode(v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrStringV(rv2i(rv).(map[uintptr]string), e)
+}
+func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeString(cUTF8, v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUintV(rv2i(rv).(map[uintptr]uint), e)
+}
+func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), e)
+}
+func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), e)
+}
+func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), e)
+}
+func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), e)
+}
+func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeUint(uint64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), e)
+}
+func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				e.encode(v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrIntV(rv2i(rv).(map[uintptr]int), e)
+}
+func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), e)
+}
+func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), e)
+}
+func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), e)
+}
+func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), e)
+}
+func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeInt(int64(v[uintptr(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), e)
+}
+func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeFloat32(v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), e)
+}
+func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeFloat64(v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), e)
+}
+func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]uint64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = uint64(k)
+			i++
+		}
+		sort.Sort(uintSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				e.encode(uintptr(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[uintptr(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				e.encode(uintptr(k2))
+				ee.EncodeBool(v[uintptr(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				e.encode(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				e.encode(k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntIntfV(rv2i(rv).(map[int]interface{}), e)
+}
+func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				e.encode(v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntStringV(rv2i(rv).(map[int]string), e)
+}
+func (_ fastpathT) EncMapIntStringV(v map[int]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeString(cUTF8, v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUintV(rv2i(rv).(map[int]uint), e)
+}
+func (_ fastpathT) EncMapIntUintV(v map[int]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUint8V(rv2i(rv).(map[int]uint8), e)
+}
+func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUint16V(rv2i(rv).(map[int]uint16), e)
+}
+func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUint32V(rv2i(rv).(map[int]uint32), e)
+}
+func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUint64V(rv2i(rv).(map[int]uint64), e)
+}
+func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeUint(uint64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntUintptrV(rv2i(rv).(map[int]uintptr), e)
+}
+func (_ fastpathT) EncMapIntUintptrV(v map[int]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				e.encode(v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntIntV(rv2i(rv).(map[int]int), e)
+}
+func (_ fastpathT) EncMapIntIntV(v map[int]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntInt8V(rv2i(rv).(map[int]int8), e)
+}
+func (_ fastpathT) EncMapIntInt8V(v map[int]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntInt16V(rv2i(rv).(map[int]int16), e)
+}
+func (_ fastpathT) EncMapIntInt16V(v map[int]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntInt32V(rv2i(rv).(map[int]int32), e)
+}
+func (_ fastpathT) EncMapIntInt32V(v map[int]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntInt64V(rv2i(rv).(map[int]int64), e)
+}
+func (_ fastpathT) EncMapIntInt64V(v map[int]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeInt(int64(v[int(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntFloat32V(rv2i(rv).(map[int]float32), e)
+}
+func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeFloat32(v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntFloat64V(rv2i(rv).(map[int]float64), e)
+}
+func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeFloat64(v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapIntBoolV(rv2i(rv).(map[int]bool), e)
+}
+func (_ fastpathT) EncMapIntBoolV(v map[int]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[int(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int(k2)))
+				ee.EncodeBool(v[int(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8IntfV(rv2i(rv).(map[int8]interface{}), e)
+}
+func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				e.encode(v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8StringV(rv2i(rv).(map[int8]string), e)
+}
+func (_ fastpathT) EncMapInt8StringV(v map[int8]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeString(cUTF8, v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8UintV(rv2i(rv).(map[int8]uint), e)
+}
+func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint8V(rv2i(rv).(map[int8]uint8), e)
+}
+func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint16V(rv2i(rv).(map[int8]uint16), e)
+}
+func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint32V(rv2i(rv).(map[int8]uint32), e)
+}
+func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Uint64V(rv2i(rv).(map[int8]uint64), e)
+}
+func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeUint(uint64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), e)
+}
+func (_ fastpathT) EncMapInt8UintptrV(v map[int8]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				e.encode(v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8IntV(rv2i(rv).(map[int8]int), e)
+}
+func (_ fastpathT) EncMapInt8IntV(v map[int8]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Int8V(rv2i(rv).(map[int8]int8), e)
+}
+func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Int16V(rv2i(rv).(map[int8]int16), e)
+}
+func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Int32V(rv2i(rv).(map[int8]int32), e)
+}
+func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Int64V(rv2i(rv).(map[int8]int64), e)
+}
+func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeInt(int64(v[int8(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Float32V(rv2i(rv).(map[int8]float32), e)
+}
+func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeFloat32(v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8Float64V(rv2i(rv).(map[int8]float64), e)
+}
+func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeFloat64(v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt8BoolV(rv2i(rv).(map[int8]bool), e)
+}
+func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int8(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[int8(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int8(k2)))
+				ee.EncodeBool(v[int8(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16IntfV(rv2i(rv).(map[int16]interface{}), e)
+}
+func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				e.encode(v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16StringV(rv2i(rv).(map[int16]string), e)
+}
+func (_ fastpathT) EncMapInt16StringV(v map[int16]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeString(cUTF8, v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16UintV(rv2i(rv).(map[int16]uint), e)
+}
+func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint8V(rv2i(rv).(map[int16]uint8), e)
+}
+func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint16V(rv2i(rv).(map[int16]uint16), e)
+}
+func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint32V(rv2i(rv).(map[int16]uint32), e)
+}
+func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Uint64V(rv2i(rv).(map[int16]uint64), e)
+}
+func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeUint(uint64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), e)
+}
+func (_ fastpathT) EncMapInt16UintptrV(v map[int16]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				e.encode(v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16IntV(rv2i(rv).(map[int16]int), e)
+}
+func (_ fastpathT) EncMapInt16IntV(v map[int16]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Int8V(rv2i(rv).(map[int16]int8), e)
+}
+func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Int16V(rv2i(rv).(map[int16]int16), e)
+}
+func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Int32V(rv2i(rv).(map[int16]int32), e)
+}
+func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Int64V(rv2i(rv).(map[int16]int64), e)
+}
+func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeInt(int64(v[int16(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Float32V(rv2i(rv).(map[int16]float32), e)
+}
+func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeFloat32(v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16Float64V(rv2i(rv).(map[int16]float64), e)
+}
+func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeFloat64(v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt16BoolV(rv2i(rv).(map[int16]bool), e)
+}
+func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int16(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[int16(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int16(k2)))
+				ee.EncodeBool(v[int16(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32IntfV(rv2i(rv).(map[int32]interface{}), e)
+}
+func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				e.encode(v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32StringV(rv2i(rv).(map[int32]string), e)
+}
+func (_ fastpathT) EncMapInt32StringV(v map[int32]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeString(cUTF8, v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32UintV(rv2i(rv).(map[int32]uint), e)
+}
+func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint8V(rv2i(rv).(map[int32]uint8), e)
+}
+func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint16V(rv2i(rv).(map[int32]uint16), e)
+}
+func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint32V(rv2i(rv).(map[int32]uint32), e)
+}
+func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Uint64V(rv2i(rv).(map[int32]uint64), e)
+}
+func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeUint(uint64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), e)
+}
+func (_ fastpathT) EncMapInt32UintptrV(v map[int32]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				e.encode(v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32IntV(rv2i(rv).(map[int32]int), e)
+}
+func (_ fastpathT) EncMapInt32IntV(v map[int32]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Int8V(rv2i(rv).(map[int32]int8), e)
+}
+func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Int16V(rv2i(rv).(map[int32]int16), e)
+}
+func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Int32V(rv2i(rv).(map[int32]int32), e)
+}
+func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Int64V(rv2i(rv).(map[int32]int64), e)
+}
+func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeInt(int64(v[int32(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Float32V(rv2i(rv).(map[int32]float32), e)
+}
+func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeFloat32(v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32Float64V(rv2i(rv).(map[int32]float64), e)
+}
+func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeFloat64(v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt32BoolV(rv2i(rv).(map[int32]bool), e)
+}
+func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int32(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[int32(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int32(k2)))
+				ee.EncodeBool(v[int32(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64IntfV(rv2i(rv).(map[int64]interface{}), e)
+}
+func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				e.encode(v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64StringV(rv2i(rv).(map[int64]string), e)
+}
+func (_ fastpathT) EncMapInt64StringV(v map[int64]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeString(cUTF8, v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64UintV(rv2i(rv).(map[int64]uint), e)
+}
+func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint8V(rv2i(rv).(map[int64]uint8), e)
+}
+func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint16V(rv2i(rv).(map[int64]uint16), e)
+}
+func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint32V(rv2i(rv).(map[int64]uint32), e)
+}
+func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Uint64V(rv2i(rv).(map[int64]uint64), e)
+}
+func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeUint(uint64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), e)
+}
+func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				e.encode(v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				e.encode(v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64IntV(rv2i(rv).(map[int64]int), e)
+}
+func (_ fastpathT) EncMapInt64IntV(v map[int64]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Int8V(rv2i(rv).(map[int64]int8), e)
+}
+func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Int16V(rv2i(rv).(map[int64]int16), e)
+}
+func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Int32V(rv2i(rv).(map[int64]int32), e)
+}
+func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Int64V(rv2i(rv).(map[int64]int64), e)
+}
+func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeInt(int64(v[int64(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Float32V(rv2i(rv).(map[int64]float32), e)
+}
+func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeFloat32(v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64Float64V(rv2i(rv).(map[int64]float64), e)
+}
+func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeFloat64(v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapInt64BoolV(rv2i(rv).(map[int64]bool), e)
+}
+func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]int64, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = int64(k)
+			i++
+		}
+		sort.Sort(intSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(int64(k2)))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[int64(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeInt(int64(int64(k2)))
+				ee.EncodeBool(v[int64(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeInt(int64(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeInt(int64(k2))
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolIntfV(rv2i(rv).(map[bool]interface{}), e)
+}
+func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				e.encode(v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolStringV(rv2i(rv).(map[bool]string), e)
+}
+func (_ fastpathT) EncMapBoolStringV(v map[bool]string, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeString(cUTF8, v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeString(cUTF8, v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeString(cUTF8, v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUintV(rv2i(rv).(map[bool]uint), e)
+}
+func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUint8V(rv2i(rv).(map[bool]uint8), e)
+}
+func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUint16V(rv2i(rv).(map[bool]uint16), e)
+}
+func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUint32V(rv2i(rv).(map[bool]uint32), e)
+}
+func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUint64V(rv2i(rv).(map[bool]uint64), e)
+}
+func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeUint(uint64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeUint(uint64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeUint(uint64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), e)
+}
+func (_ fastpathT) EncMapBoolUintptrV(v map[bool]uintptr, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				e.encode(v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				e.encode(v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				e.encode(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				e.encode(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolIntV(rv2i(rv).(map[bool]int), e)
+}
+func (_ fastpathT) EncMapBoolIntV(v map[bool]int, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolInt8V(rv2i(rv).(map[bool]int8), e)
+}
+func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolInt16V(rv2i(rv).(map[bool]int16), e)
+}
+func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolInt32V(rv2i(rv).(map[bool]int32), e)
+}
+func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolInt64V(rv2i(rv).(map[bool]int64), e)
+}
+func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeInt(int64(v[bool(k2)]))
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeInt(int64(v2))
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeInt(int64(v2))
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolFloat32V(rv2i(rv).(map[bool]float32), e)
+}
+func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeFloat32(v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat32(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeFloat32(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolFloat64V(rv2i(rv).(map[bool]float64), e)
+}
+func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeFloat64(v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeFloat64(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeFloat64(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+func (e *Encoder) fastpathEncMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.EncMapBoolBoolV(rv2i(rv).(map[bool]bool), e)
+}
+func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, e *Encoder) {
+	if v == nil {
+		e.e.EncodeNil()
+		return
+	}
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		v2 := make([]bool, len(v))
+		var i int
+		for k, _ := range v {
+			v2[i] = bool(k)
+			i++
+		}
+		sort.Sort(boolSlice(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(bool(k2))
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v[bool(k2)])
+			}
+		} else {
+			for _, k2 := range v2 {
+				ee.EncodeBool(bool(k2))
+				ee.EncodeBool(v[bool(k2)])
+			}
+		}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				ee.EncodeBool(k2)
+				ee.WriteMapElemValue()
+				ee.EncodeBool(v2)
+			}
+		} else {
+			for k2, v2 := range v {
+				ee.EncodeBool(k2)
+				ee.EncodeBool(v2)
+			}
+		}
+	}
+	ee.WriteMapEnd()
+}
+
+// -- decode
+
+// -- -- fast path type switch
+func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
+	var changed bool
+	switch v := iv.(type) {
+
+	case []interface{}:
+		var v2 []interface{}
+		v2, changed = fastpathTV.DecSliceIntfV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]interface{}:
+		var v2 []interface{}
+		v2, changed = fastpathTV.DecSliceIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []string:
+		var v2 []string
+		v2, changed = fastpathTV.DecSliceStringV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]string:
+		var v2 []string
+		v2, changed = fastpathTV.DecSliceStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []float32:
+		var v2 []float32
+		v2, changed = fastpathTV.DecSliceFloat32V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]float32:
+		var v2 []float32
+		v2, changed = fastpathTV.DecSliceFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []float64:
+		var v2 []float64
+		v2, changed = fastpathTV.DecSliceFloat64V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]float64:
+		var v2 []float64
+		v2, changed = fastpathTV.DecSliceFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []uint:
+		var v2 []uint
+		v2, changed = fastpathTV.DecSliceUintV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]uint:
+		var v2 []uint
+		v2, changed = fastpathTV.DecSliceUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []uint16:
+		var v2 []uint16
+		v2, changed = fastpathTV.DecSliceUint16V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]uint16:
+		var v2 []uint16
+		v2, changed = fastpathTV.DecSliceUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []uint32:
+		var v2 []uint32
+		v2, changed = fastpathTV.DecSliceUint32V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]uint32:
+		var v2 []uint32
+		v2, changed = fastpathTV.DecSliceUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []uint64:
+		var v2 []uint64
+		v2, changed = fastpathTV.DecSliceUint64V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]uint64:
+		var v2 []uint64
+		v2, changed = fastpathTV.DecSliceUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []uintptr:
+		var v2 []uintptr
+		v2, changed = fastpathTV.DecSliceUintptrV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]uintptr:
+		var v2 []uintptr
+		v2, changed = fastpathTV.DecSliceUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []int:
+		var v2 []int
+		v2, changed = fastpathTV.DecSliceIntV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]int:
+		var v2 []int
+		v2, changed = fastpathTV.DecSliceIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []int8:
+		var v2 []int8
+		v2, changed = fastpathTV.DecSliceInt8V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]int8:
+		var v2 []int8
+		v2, changed = fastpathTV.DecSliceInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []int16:
+		var v2 []int16
+		v2, changed = fastpathTV.DecSliceInt16V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]int16:
+		var v2 []int16
+		v2, changed = fastpathTV.DecSliceInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []int32:
+		var v2 []int32
+		v2, changed = fastpathTV.DecSliceInt32V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]int32:
+		var v2 []int32
+		v2, changed = fastpathTV.DecSliceInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []int64:
+		var v2 []int64
+		v2, changed = fastpathTV.DecSliceInt64V(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]int64:
+		var v2 []int64
+		v2, changed = fastpathTV.DecSliceInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case []bool:
+		var v2 []bool
+		v2, changed = fastpathTV.DecSliceBoolV(v, false, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]bool:
+		var v2 []bool
+		v2, changed = fastpathTV.DecSliceBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+
+	case map[interface{}]interface{}:
+		fastpathTV.DecMapIntfIntfV(v, false, d)
+	case *map[interface{}]interface{}:
+		var v2 map[interface{}]interface{}
+		v2, changed = fastpathTV.DecMapIntfIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]string:
+		fastpathTV.DecMapIntfStringV(v, false, d)
+	case *map[interface{}]string:
+		var v2 map[interface{}]string
+		v2, changed = fastpathTV.DecMapIntfStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uint:
+		fastpathTV.DecMapIntfUintV(v, false, d)
+	case *map[interface{}]uint:
+		var v2 map[interface{}]uint
+		v2, changed = fastpathTV.DecMapIntfUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uint8:
+		fastpathTV.DecMapIntfUint8V(v, false, d)
+	case *map[interface{}]uint8:
+		var v2 map[interface{}]uint8
+		v2, changed = fastpathTV.DecMapIntfUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uint16:
+		fastpathTV.DecMapIntfUint16V(v, false, d)
+	case *map[interface{}]uint16:
+		var v2 map[interface{}]uint16
+		v2, changed = fastpathTV.DecMapIntfUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uint32:
+		fastpathTV.DecMapIntfUint32V(v, false, d)
+	case *map[interface{}]uint32:
+		var v2 map[interface{}]uint32
+		v2, changed = fastpathTV.DecMapIntfUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uint64:
+		fastpathTV.DecMapIntfUint64V(v, false, d)
+	case *map[interface{}]uint64:
+		var v2 map[interface{}]uint64
+		v2, changed = fastpathTV.DecMapIntfUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]uintptr:
+		fastpathTV.DecMapIntfUintptrV(v, false, d)
+	case *map[interface{}]uintptr:
+		var v2 map[interface{}]uintptr
+		v2, changed = fastpathTV.DecMapIntfUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]int:
+		fastpathTV.DecMapIntfIntV(v, false, d)
+	case *map[interface{}]int:
+		var v2 map[interface{}]int
+		v2, changed = fastpathTV.DecMapIntfIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]int8:
+		fastpathTV.DecMapIntfInt8V(v, false, d)
+	case *map[interface{}]int8:
+		var v2 map[interface{}]int8
+		v2, changed = fastpathTV.DecMapIntfInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]int16:
+		fastpathTV.DecMapIntfInt16V(v, false, d)
+	case *map[interface{}]int16:
+		var v2 map[interface{}]int16
+		v2, changed = fastpathTV.DecMapIntfInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]int32:
+		fastpathTV.DecMapIntfInt32V(v, false, d)
+	case *map[interface{}]int32:
+		var v2 map[interface{}]int32
+		v2, changed = fastpathTV.DecMapIntfInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]int64:
+		fastpathTV.DecMapIntfInt64V(v, false, d)
+	case *map[interface{}]int64:
+		var v2 map[interface{}]int64
+		v2, changed = fastpathTV.DecMapIntfInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]float32:
+		fastpathTV.DecMapIntfFloat32V(v, false, d)
+	case *map[interface{}]float32:
+		var v2 map[interface{}]float32
+		v2, changed = fastpathTV.DecMapIntfFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]float64:
+		fastpathTV.DecMapIntfFloat64V(v, false, d)
+	case *map[interface{}]float64:
+		var v2 map[interface{}]float64
+		v2, changed = fastpathTV.DecMapIntfFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[interface{}]bool:
+		fastpathTV.DecMapIntfBoolV(v, false, d)
+	case *map[interface{}]bool:
+		var v2 map[interface{}]bool
+		v2, changed = fastpathTV.DecMapIntfBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]interface{}:
+		fastpathTV.DecMapStringIntfV(v, false, d)
+	case *map[string]interface{}:
+		var v2 map[string]interface{}
+		v2, changed = fastpathTV.DecMapStringIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]string:
+		fastpathTV.DecMapStringStringV(v, false, d)
+	case *map[string]string:
+		var v2 map[string]string
+		v2, changed = fastpathTV.DecMapStringStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uint:
+		fastpathTV.DecMapStringUintV(v, false, d)
+	case *map[string]uint:
+		var v2 map[string]uint
+		v2, changed = fastpathTV.DecMapStringUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uint8:
+		fastpathTV.DecMapStringUint8V(v, false, d)
+	case *map[string]uint8:
+		var v2 map[string]uint8
+		v2, changed = fastpathTV.DecMapStringUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uint16:
+		fastpathTV.DecMapStringUint16V(v, false, d)
+	case *map[string]uint16:
+		var v2 map[string]uint16
+		v2, changed = fastpathTV.DecMapStringUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uint32:
+		fastpathTV.DecMapStringUint32V(v, false, d)
+	case *map[string]uint32:
+		var v2 map[string]uint32
+		v2, changed = fastpathTV.DecMapStringUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uint64:
+		fastpathTV.DecMapStringUint64V(v, false, d)
+	case *map[string]uint64:
+		var v2 map[string]uint64
+		v2, changed = fastpathTV.DecMapStringUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]uintptr:
+		fastpathTV.DecMapStringUintptrV(v, false, d)
+	case *map[string]uintptr:
+		var v2 map[string]uintptr
+		v2, changed = fastpathTV.DecMapStringUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]int:
+		fastpathTV.DecMapStringIntV(v, false, d)
+	case *map[string]int:
+		var v2 map[string]int
+		v2, changed = fastpathTV.DecMapStringIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]int8:
+		fastpathTV.DecMapStringInt8V(v, false, d)
+	case *map[string]int8:
+		var v2 map[string]int8
+		v2, changed = fastpathTV.DecMapStringInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]int16:
+		fastpathTV.DecMapStringInt16V(v, false, d)
+	case *map[string]int16:
+		var v2 map[string]int16
+		v2, changed = fastpathTV.DecMapStringInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]int32:
+		fastpathTV.DecMapStringInt32V(v, false, d)
+	case *map[string]int32:
+		var v2 map[string]int32
+		v2, changed = fastpathTV.DecMapStringInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]int64:
+		fastpathTV.DecMapStringInt64V(v, false, d)
+	case *map[string]int64:
+		var v2 map[string]int64
+		v2, changed = fastpathTV.DecMapStringInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]float32:
+		fastpathTV.DecMapStringFloat32V(v, false, d)
+	case *map[string]float32:
+		var v2 map[string]float32
+		v2, changed = fastpathTV.DecMapStringFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]float64:
+		fastpathTV.DecMapStringFloat64V(v, false, d)
+	case *map[string]float64:
+		var v2 map[string]float64
+		v2, changed = fastpathTV.DecMapStringFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[string]bool:
+		fastpathTV.DecMapStringBoolV(v, false, d)
+	case *map[string]bool:
+		var v2 map[string]bool
+		v2, changed = fastpathTV.DecMapStringBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]interface{}:
+		fastpathTV.DecMapFloat32IntfV(v, false, d)
+	case *map[float32]interface{}:
+		var v2 map[float32]interface{}
+		v2, changed = fastpathTV.DecMapFloat32IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]string:
+		fastpathTV.DecMapFloat32StringV(v, false, d)
+	case *map[float32]string:
+		var v2 map[float32]string
+		v2, changed = fastpathTV.DecMapFloat32StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uint:
+		fastpathTV.DecMapFloat32UintV(v, false, d)
+	case *map[float32]uint:
+		var v2 map[float32]uint
+		v2, changed = fastpathTV.DecMapFloat32UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uint8:
+		fastpathTV.DecMapFloat32Uint8V(v, false, d)
+	case *map[float32]uint8:
+		var v2 map[float32]uint8
+		v2, changed = fastpathTV.DecMapFloat32Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uint16:
+		fastpathTV.DecMapFloat32Uint16V(v, false, d)
+	case *map[float32]uint16:
+		var v2 map[float32]uint16
+		v2, changed = fastpathTV.DecMapFloat32Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uint32:
+		fastpathTV.DecMapFloat32Uint32V(v, false, d)
+	case *map[float32]uint32:
+		var v2 map[float32]uint32
+		v2, changed = fastpathTV.DecMapFloat32Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uint64:
+		fastpathTV.DecMapFloat32Uint64V(v, false, d)
+	case *map[float32]uint64:
+		var v2 map[float32]uint64
+		v2, changed = fastpathTV.DecMapFloat32Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]uintptr:
+		fastpathTV.DecMapFloat32UintptrV(v, false, d)
+	case *map[float32]uintptr:
+		var v2 map[float32]uintptr
+		v2, changed = fastpathTV.DecMapFloat32UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]int:
+		fastpathTV.DecMapFloat32IntV(v, false, d)
+	case *map[float32]int:
+		var v2 map[float32]int
+		v2, changed = fastpathTV.DecMapFloat32IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]int8:
+		fastpathTV.DecMapFloat32Int8V(v, false, d)
+	case *map[float32]int8:
+		var v2 map[float32]int8
+		v2, changed = fastpathTV.DecMapFloat32Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]int16:
+		fastpathTV.DecMapFloat32Int16V(v, false, d)
+	case *map[float32]int16:
+		var v2 map[float32]int16
+		v2, changed = fastpathTV.DecMapFloat32Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]int32:
+		fastpathTV.DecMapFloat32Int32V(v, false, d)
+	case *map[float32]int32:
+		var v2 map[float32]int32
+		v2, changed = fastpathTV.DecMapFloat32Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]int64:
+		fastpathTV.DecMapFloat32Int64V(v, false, d)
+	case *map[float32]int64:
+		var v2 map[float32]int64
+		v2, changed = fastpathTV.DecMapFloat32Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]float32:
+		fastpathTV.DecMapFloat32Float32V(v, false, d)
+	case *map[float32]float32:
+		var v2 map[float32]float32
+		v2, changed = fastpathTV.DecMapFloat32Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]float64:
+		fastpathTV.DecMapFloat32Float64V(v, false, d)
+	case *map[float32]float64:
+		var v2 map[float32]float64
+		v2, changed = fastpathTV.DecMapFloat32Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float32]bool:
+		fastpathTV.DecMapFloat32BoolV(v, false, d)
+	case *map[float32]bool:
+		var v2 map[float32]bool
+		v2, changed = fastpathTV.DecMapFloat32BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]interface{}:
+		fastpathTV.DecMapFloat64IntfV(v, false, d)
+	case *map[float64]interface{}:
+		var v2 map[float64]interface{}
+		v2, changed = fastpathTV.DecMapFloat64IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]string:
+		fastpathTV.DecMapFloat64StringV(v, false, d)
+	case *map[float64]string:
+		var v2 map[float64]string
+		v2, changed = fastpathTV.DecMapFloat64StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uint:
+		fastpathTV.DecMapFloat64UintV(v, false, d)
+	case *map[float64]uint:
+		var v2 map[float64]uint
+		v2, changed = fastpathTV.DecMapFloat64UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uint8:
+		fastpathTV.DecMapFloat64Uint8V(v, false, d)
+	case *map[float64]uint8:
+		var v2 map[float64]uint8
+		v2, changed = fastpathTV.DecMapFloat64Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uint16:
+		fastpathTV.DecMapFloat64Uint16V(v, false, d)
+	case *map[float64]uint16:
+		var v2 map[float64]uint16
+		v2, changed = fastpathTV.DecMapFloat64Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uint32:
+		fastpathTV.DecMapFloat64Uint32V(v, false, d)
+	case *map[float64]uint32:
+		var v2 map[float64]uint32
+		v2, changed = fastpathTV.DecMapFloat64Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uint64:
+		fastpathTV.DecMapFloat64Uint64V(v, false, d)
+	case *map[float64]uint64:
+		var v2 map[float64]uint64
+		v2, changed = fastpathTV.DecMapFloat64Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]uintptr:
+		fastpathTV.DecMapFloat64UintptrV(v, false, d)
+	case *map[float64]uintptr:
+		var v2 map[float64]uintptr
+		v2, changed = fastpathTV.DecMapFloat64UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]int:
+		fastpathTV.DecMapFloat64IntV(v, false, d)
+	case *map[float64]int:
+		var v2 map[float64]int
+		v2, changed = fastpathTV.DecMapFloat64IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]int8:
+		fastpathTV.DecMapFloat64Int8V(v, false, d)
+	case *map[float64]int8:
+		var v2 map[float64]int8
+		v2, changed = fastpathTV.DecMapFloat64Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]int16:
+		fastpathTV.DecMapFloat64Int16V(v, false, d)
+	case *map[float64]int16:
+		var v2 map[float64]int16
+		v2, changed = fastpathTV.DecMapFloat64Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]int32:
+		fastpathTV.DecMapFloat64Int32V(v, false, d)
+	case *map[float64]int32:
+		var v2 map[float64]int32
+		v2, changed = fastpathTV.DecMapFloat64Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]int64:
+		fastpathTV.DecMapFloat64Int64V(v, false, d)
+	case *map[float64]int64:
+		var v2 map[float64]int64
+		v2, changed = fastpathTV.DecMapFloat64Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]float32:
+		fastpathTV.DecMapFloat64Float32V(v, false, d)
+	case *map[float64]float32:
+		var v2 map[float64]float32
+		v2, changed = fastpathTV.DecMapFloat64Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]float64:
+		fastpathTV.DecMapFloat64Float64V(v, false, d)
+	case *map[float64]float64:
+		var v2 map[float64]float64
+		v2, changed = fastpathTV.DecMapFloat64Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[float64]bool:
+		fastpathTV.DecMapFloat64BoolV(v, false, d)
+	case *map[float64]bool:
+		var v2 map[float64]bool
+		v2, changed = fastpathTV.DecMapFloat64BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]interface{}:
+		fastpathTV.DecMapUintIntfV(v, false, d)
+	case *map[uint]interface{}:
+		var v2 map[uint]interface{}
+		v2, changed = fastpathTV.DecMapUintIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]string:
+		fastpathTV.DecMapUintStringV(v, false, d)
+	case *map[uint]string:
+		var v2 map[uint]string
+		v2, changed = fastpathTV.DecMapUintStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uint:
+		fastpathTV.DecMapUintUintV(v, false, d)
+	case *map[uint]uint:
+		var v2 map[uint]uint
+		v2, changed = fastpathTV.DecMapUintUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uint8:
+		fastpathTV.DecMapUintUint8V(v, false, d)
+	case *map[uint]uint8:
+		var v2 map[uint]uint8
+		v2, changed = fastpathTV.DecMapUintUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uint16:
+		fastpathTV.DecMapUintUint16V(v, false, d)
+	case *map[uint]uint16:
+		var v2 map[uint]uint16
+		v2, changed = fastpathTV.DecMapUintUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uint32:
+		fastpathTV.DecMapUintUint32V(v, false, d)
+	case *map[uint]uint32:
+		var v2 map[uint]uint32
+		v2, changed = fastpathTV.DecMapUintUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uint64:
+		fastpathTV.DecMapUintUint64V(v, false, d)
+	case *map[uint]uint64:
+		var v2 map[uint]uint64
+		v2, changed = fastpathTV.DecMapUintUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]uintptr:
+		fastpathTV.DecMapUintUintptrV(v, false, d)
+	case *map[uint]uintptr:
+		var v2 map[uint]uintptr
+		v2, changed = fastpathTV.DecMapUintUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]int:
+		fastpathTV.DecMapUintIntV(v, false, d)
+	case *map[uint]int:
+		var v2 map[uint]int
+		v2, changed = fastpathTV.DecMapUintIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]int8:
+		fastpathTV.DecMapUintInt8V(v, false, d)
+	case *map[uint]int8:
+		var v2 map[uint]int8
+		v2, changed = fastpathTV.DecMapUintInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]int16:
+		fastpathTV.DecMapUintInt16V(v, false, d)
+	case *map[uint]int16:
+		var v2 map[uint]int16
+		v2, changed = fastpathTV.DecMapUintInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]int32:
+		fastpathTV.DecMapUintInt32V(v, false, d)
+	case *map[uint]int32:
+		var v2 map[uint]int32
+		v2, changed = fastpathTV.DecMapUintInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]int64:
+		fastpathTV.DecMapUintInt64V(v, false, d)
+	case *map[uint]int64:
+		var v2 map[uint]int64
+		v2, changed = fastpathTV.DecMapUintInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]float32:
+		fastpathTV.DecMapUintFloat32V(v, false, d)
+	case *map[uint]float32:
+		var v2 map[uint]float32
+		v2, changed = fastpathTV.DecMapUintFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]float64:
+		fastpathTV.DecMapUintFloat64V(v, false, d)
+	case *map[uint]float64:
+		var v2 map[uint]float64
+		v2, changed = fastpathTV.DecMapUintFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint]bool:
+		fastpathTV.DecMapUintBoolV(v, false, d)
+	case *map[uint]bool:
+		var v2 map[uint]bool
+		v2, changed = fastpathTV.DecMapUintBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]interface{}:
+		fastpathTV.DecMapUint8IntfV(v, false, d)
+	case *map[uint8]interface{}:
+		var v2 map[uint8]interface{}
+		v2, changed = fastpathTV.DecMapUint8IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]string:
+		fastpathTV.DecMapUint8StringV(v, false, d)
+	case *map[uint8]string:
+		var v2 map[uint8]string
+		v2, changed = fastpathTV.DecMapUint8StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uint:
+		fastpathTV.DecMapUint8UintV(v, false, d)
+	case *map[uint8]uint:
+		var v2 map[uint8]uint
+		v2, changed = fastpathTV.DecMapUint8UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uint8:
+		fastpathTV.DecMapUint8Uint8V(v, false, d)
+	case *map[uint8]uint8:
+		var v2 map[uint8]uint8
+		v2, changed = fastpathTV.DecMapUint8Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uint16:
+		fastpathTV.DecMapUint8Uint16V(v, false, d)
+	case *map[uint8]uint16:
+		var v2 map[uint8]uint16
+		v2, changed = fastpathTV.DecMapUint8Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uint32:
+		fastpathTV.DecMapUint8Uint32V(v, false, d)
+	case *map[uint8]uint32:
+		var v2 map[uint8]uint32
+		v2, changed = fastpathTV.DecMapUint8Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uint64:
+		fastpathTV.DecMapUint8Uint64V(v, false, d)
+	case *map[uint8]uint64:
+		var v2 map[uint8]uint64
+		v2, changed = fastpathTV.DecMapUint8Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]uintptr:
+		fastpathTV.DecMapUint8UintptrV(v, false, d)
+	case *map[uint8]uintptr:
+		var v2 map[uint8]uintptr
+		v2, changed = fastpathTV.DecMapUint8UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]int:
+		fastpathTV.DecMapUint8IntV(v, false, d)
+	case *map[uint8]int:
+		var v2 map[uint8]int
+		v2, changed = fastpathTV.DecMapUint8IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]int8:
+		fastpathTV.DecMapUint8Int8V(v, false, d)
+	case *map[uint8]int8:
+		var v2 map[uint8]int8
+		v2, changed = fastpathTV.DecMapUint8Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]int16:
+		fastpathTV.DecMapUint8Int16V(v, false, d)
+	case *map[uint8]int16:
+		var v2 map[uint8]int16
+		v2, changed = fastpathTV.DecMapUint8Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]int32:
+		fastpathTV.DecMapUint8Int32V(v, false, d)
+	case *map[uint8]int32:
+		var v2 map[uint8]int32
+		v2, changed = fastpathTV.DecMapUint8Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]int64:
+		fastpathTV.DecMapUint8Int64V(v, false, d)
+	case *map[uint8]int64:
+		var v2 map[uint8]int64
+		v2, changed = fastpathTV.DecMapUint8Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]float32:
+		fastpathTV.DecMapUint8Float32V(v, false, d)
+	case *map[uint8]float32:
+		var v2 map[uint8]float32
+		v2, changed = fastpathTV.DecMapUint8Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]float64:
+		fastpathTV.DecMapUint8Float64V(v, false, d)
+	case *map[uint8]float64:
+		var v2 map[uint8]float64
+		v2, changed = fastpathTV.DecMapUint8Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint8]bool:
+		fastpathTV.DecMapUint8BoolV(v, false, d)
+	case *map[uint8]bool:
+		var v2 map[uint8]bool
+		v2, changed = fastpathTV.DecMapUint8BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]interface{}:
+		fastpathTV.DecMapUint16IntfV(v, false, d)
+	case *map[uint16]interface{}:
+		var v2 map[uint16]interface{}
+		v2, changed = fastpathTV.DecMapUint16IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]string:
+		fastpathTV.DecMapUint16StringV(v, false, d)
+	case *map[uint16]string:
+		var v2 map[uint16]string
+		v2, changed = fastpathTV.DecMapUint16StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uint:
+		fastpathTV.DecMapUint16UintV(v, false, d)
+	case *map[uint16]uint:
+		var v2 map[uint16]uint
+		v2, changed = fastpathTV.DecMapUint16UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uint8:
+		fastpathTV.DecMapUint16Uint8V(v, false, d)
+	case *map[uint16]uint8:
+		var v2 map[uint16]uint8
+		v2, changed = fastpathTV.DecMapUint16Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uint16:
+		fastpathTV.DecMapUint16Uint16V(v, false, d)
+	case *map[uint16]uint16:
+		var v2 map[uint16]uint16
+		v2, changed = fastpathTV.DecMapUint16Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uint32:
+		fastpathTV.DecMapUint16Uint32V(v, false, d)
+	case *map[uint16]uint32:
+		var v2 map[uint16]uint32
+		v2, changed = fastpathTV.DecMapUint16Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uint64:
+		fastpathTV.DecMapUint16Uint64V(v, false, d)
+	case *map[uint16]uint64:
+		var v2 map[uint16]uint64
+		v2, changed = fastpathTV.DecMapUint16Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]uintptr:
+		fastpathTV.DecMapUint16UintptrV(v, false, d)
+	case *map[uint16]uintptr:
+		var v2 map[uint16]uintptr
+		v2, changed = fastpathTV.DecMapUint16UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]int:
+		fastpathTV.DecMapUint16IntV(v, false, d)
+	case *map[uint16]int:
+		var v2 map[uint16]int
+		v2, changed = fastpathTV.DecMapUint16IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]int8:
+		fastpathTV.DecMapUint16Int8V(v, false, d)
+	case *map[uint16]int8:
+		var v2 map[uint16]int8
+		v2, changed = fastpathTV.DecMapUint16Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]int16:
+		fastpathTV.DecMapUint16Int16V(v, false, d)
+	case *map[uint16]int16:
+		var v2 map[uint16]int16
+		v2, changed = fastpathTV.DecMapUint16Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]int32:
+		fastpathTV.DecMapUint16Int32V(v, false, d)
+	case *map[uint16]int32:
+		var v2 map[uint16]int32
+		v2, changed = fastpathTV.DecMapUint16Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]int64:
+		fastpathTV.DecMapUint16Int64V(v, false, d)
+	case *map[uint16]int64:
+		var v2 map[uint16]int64
+		v2, changed = fastpathTV.DecMapUint16Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]float32:
+		fastpathTV.DecMapUint16Float32V(v, false, d)
+	case *map[uint16]float32:
+		var v2 map[uint16]float32
+		v2, changed = fastpathTV.DecMapUint16Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]float64:
+		fastpathTV.DecMapUint16Float64V(v, false, d)
+	case *map[uint16]float64:
+		var v2 map[uint16]float64
+		v2, changed = fastpathTV.DecMapUint16Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint16]bool:
+		fastpathTV.DecMapUint16BoolV(v, false, d)
+	case *map[uint16]bool:
+		var v2 map[uint16]bool
+		v2, changed = fastpathTV.DecMapUint16BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]interface{}:
+		fastpathTV.DecMapUint32IntfV(v, false, d)
+	case *map[uint32]interface{}:
+		var v2 map[uint32]interface{}
+		v2, changed = fastpathTV.DecMapUint32IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]string:
+		fastpathTV.DecMapUint32StringV(v, false, d)
+	case *map[uint32]string:
+		var v2 map[uint32]string
+		v2, changed = fastpathTV.DecMapUint32StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uint:
+		fastpathTV.DecMapUint32UintV(v, false, d)
+	case *map[uint32]uint:
+		var v2 map[uint32]uint
+		v2, changed = fastpathTV.DecMapUint32UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uint8:
+		fastpathTV.DecMapUint32Uint8V(v, false, d)
+	case *map[uint32]uint8:
+		var v2 map[uint32]uint8
+		v2, changed = fastpathTV.DecMapUint32Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uint16:
+		fastpathTV.DecMapUint32Uint16V(v, false, d)
+	case *map[uint32]uint16:
+		var v2 map[uint32]uint16
+		v2, changed = fastpathTV.DecMapUint32Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uint32:
+		fastpathTV.DecMapUint32Uint32V(v, false, d)
+	case *map[uint32]uint32:
+		var v2 map[uint32]uint32
+		v2, changed = fastpathTV.DecMapUint32Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uint64:
+		fastpathTV.DecMapUint32Uint64V(v, false, d)
+	case *map[uint32]uint64:
+		var v2 map[uint32]uint64
+		v2, changed = fastpathTV.DecMapUint32Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]uintptr:
+		fastpathTV.DecMapUint32UintptrV(v, false, d)
+	case *map[uint32]uintptr:
+		var v2 map[uint32]uintptr
+		v2, changed = fastpathTV.DecMapUint32UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]int:
+		fastpathTV.DecMapUint32IntV(v, false, d)
+	case *map[uint32]int:
+		var v2 map[uint32]int
+		v2, changed = fastpathTV.DecMapUint32IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]int8:
+		fastpathTV.DecMapUint32Int8V(v, false, d)
+	case *map[uint32]int8:
+		var v2 map[uint32]int8
+		v2, changed = fastpathTV.DecMapUint32Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]int16:
+		fastpathTV.DecMapUint32Int16V(v, false, d)
+	case *map[uint32]int16:
+		var v2 map[uint32]int16
+		v2, changed = fastpathTV.DecMapUint32Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]int32:
+		fastpathTV.DecMapUint32Int32V(v, false, d)
+	case *map[uint32]int32:
+		var v2 map[uint32]int32
+		v2, changed = fastpathTV.DecMapUint32Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]int64:
+		fastpathTV.DecMapUint32Int64V(v, false, d)
+	case *map[uint32]int64:
+		var v2 map[uint32]int64
+		v2, changed = fastpathTV.DecMapUint32Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]float32:
+		fastpathTV.DecMapUint32Float32V(v, false, d)
+	case *map[uint32]float32:
+		var v2 map[uint32]float32
+		v2, changed = fastpathTV.DecMapUint32Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]float64:
+		fastpathTV.DecMapUint32Float64V(v, false, d)
+	case *map[uint32]float64:
+		var v2 map[uint32]float64
+		v2, changed = fastpathTV.DecMapUint32Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint32]bool:
+		fastpathTV.DecMapUint32BoolV(v, false, d)
+	case *map[uint32]bool:
+		var v2 map[uint32]bool
+		v2, changed = fastpathTV.DecMapUint32BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]interface{}:
+		fastpathTV.DecMapUint64IntfV(v, false, d)
+	case *map[uint64]interface{}:
+		var v2 map[uint64]interface{}
+		v2, changed = fastpathTV.DecMapUint64IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]string:
+		fastpathTV.DecMapUint64StringV(v, false, d)
+	case *map[uint64]string:
+		var v2 map[uint64]string
+		v2, changed = fastpathTV.DecMapUint64StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uint:
+		fastpathTV.DecMapUint64UintV(v, false, d)
+	case *map[uint64]uint:
+		var v2 map[uint64]uint
+		v2, changed = fastpathTV.DecMapUint64UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uint8:
+		fastpathTV.DecMapUint64Uint8V(v, false, d)
+	case *map[uint64]uint8:
+		var v2 map[uint64]uint8
+		v2, changed = fastpathTV.DecMapUint64Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uint16:
+		fastpathTV.DecMapUint64Uint16V(v, false, d)
+	case *map[uint64]uint16:
+		var v2 map[uint64]uint16
+		v2, changed = fastpathTV.DecMapUint64Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uint32:
+		fastpathTV.DecMapUint64Uint32V(v, false, d)
+	case *map[uint64]uint32:
+		var v2 map[uint64]uint32
+		v2, changed = fastpathTV.DecMapUint64Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uint64:
+		fastpathTV.DecMapUint64Uint64V(v, false, d)
+	case *map[uint64]uint64:
+		var v2 map[uint64]uint64
+		v2, changed = fastpathTV.DecMapUint64Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]uintptr:
+		fastpathTV.DecMapUint64UintptrV(v, false, d)
+	case *map[uint64]uintptr:
+		var v2 map[uint64]uintptr
+		v2, changed = fastpathTV.DecMapUint64UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]int:
+		fastpathTV.DecMapUint64IntV(v, false, d)
+	case *map[uint64]int:
+		var v2 map[uint64]int
+		v2, changed = fastpathTV.DecMapUint64IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]int8:
+		fastpathTV.DecMapUint64Int8V(v, false, d)
+	case *map[uint64]int8:
+		var v2 map[uint64]int8
+		v2, changed = fastpathTV.DecMapUint64Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]int16:
+		fastpathTV.DecMapUint64Int16V(v, false, d)
+	case *map[uint64]int16:
+		var v2 map[uint64]int16
+		v2, changed = fastpathTV.DecMapUint64Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]int32:
+		fastpathTV.DecMapUint64Int32V(v, false, d)
+	case *map[uint64]int32:
+		var v2 map[uint64]int32
+		v2, changed = fastpathTV.DecMapUint64Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]int64:
+		fastpathTV.DecMapUint64Int64V(v, false, d)
+	case *map[uint64]int64:
+		var v2 map[uint64]int64
+		v2, changed = fastpathTV.DecMapUint64Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]float32:
+		fastpathTV.DecMapUint64Float32V(v, false, d)
+	case *map[uint64]float32:
+		var v2 map[uint64]float32
+		v2, changed = fastpathTV.DecMapUint64Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]float64:
+		fastpathTV.DecMapUint64Float64V(v, false, d)
+	case *map[uint64]float64:
+		var v2 map[uint64]float64
+		v2, changed = fastpathTV.DecMapUint64Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uint64]bool:
+		fastpathTV.DecMapUint64BoolV(v, false, d)
+	case *map[uint64]bool:
+		var v2 map[uint64]bool
+		v2, changed = fastpathTV.DecMapUint64BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]interface{}:
+		fastpathTV.DecMapUintptrIntfV(v, false, d)
+	case *map[uintptr]interface{}:
+		var v2 map[uintptr]interface{}
+		v2, changed = fastpathTV.DecMapUintptrIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]string:
+		fastpathTV.DecMapUintptrStringV(v, false, d)
+	case *map[uintptr]string:
+		var v2 map[uintptr]string
+		v2, changed = fastpathTV.DecMapUintptrStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uint:
+		fastpathTV.DecMapUintptrUintV(v, false, d)
+	case *map[uintptr]uint:
+		var v2 map[uintptr]uint
+		v2, changed = fastpathTV.DecMapUintptrUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uint8:
+		fastpathTV.DecMapUintptrUint8V(v, false, d)
+	case *map[uintptr]uint8:
+		var v2 map[uintptr]uint8
+		v2, changed = fastpathTV.DecMapUintptrUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uint16:
+		fastpathTV.DecMapUintptrUint16V(v, false, d)
+	case *map[uintptr]uint16:
+		var v2 map[uintptr]uint16
+		v2, changed = fastpathTV.DecMapUintptrUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uint32:
+		fastpathTV.DecMapUintptrUint32V(v, false, d)
+	case *map[uintptr]uint32:
+		var v2 map[uintptr]uint32
+		v2, changed = fastpathTV.DecMapUintptrUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uint64:
+		fastpathTV.DecMapUintptrUint64V(v, false, d)
+	case *map[uintptr]uint64:
+		var v2 map[uintptr]uint64
+		v2, changed = fastpathTV.DecMapUintptrUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]uintptr:
+		fastpathTV.DecMapUintptrUintptrV(v, false, d)
+	case *map[uintptr]uintptr:
+		var v2 map[uintptr]uintptr
+		v2, changed = fastpathTV.DecMapUintptrUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]int:
+		fastpathTV.DecMapUintptrIntV(v, false, d)
+	case *map[uintptr]int:
+		var v2 map[uintptr]int
+		v2, changed = fastpathTV.DecMapUintptrIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]int8:
+		fastpathTV.DecMapUintptrInt8V(v, false, d)
+	case *map[uintptr]int8:
+		var v2 map[uintptr]int8
+		v2, changed = fastpathTV.DecMapUintptrInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]int16:
+		fastpathTV.DecMapUintptrInt16V(v, false, d)
+	case *map[uintptr]int16:
+		var v2 map[uintptr]int16
+		v2, changed = fastpathTV.DecMapUintptrInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]int32:
+		fastpathTV.DecMapUintptrInt32V(v, false, d)
+	case *map[uintptr]int32:
+		var v2 map[uintptr]int32
+		v2, changed = fastpathTV.DecMapUintptrInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]int64:
+		fastpathTV.DecMapUintptrInt64V(v, false, d)
+	case *map[uintptr]int64:
+		var v2 map[uintptr]int64
+		v2, changed = fastpathTV.DecMapUintptrInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]float32:
+		fastpathTV.DecMapUintptrFloat32V(v, false, d)
+	case *map[uintptr]float32:
+		var v2 map[uintptr]float32
+		v2, changed = fastpathTV.DecMapUintptrFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]float64:
+		fastpathTV.DecMapUintptrFloat64V(v, false, d)
+	case *map[uintptr]float64:
+		var v2 map[uintptr]float64
+		v2, changed = fastpathTV.DecMapUintptrFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[uintptr]bool:
+		fastpathTV.DecMapUintptrBoolV(v, false, d)
+	case *map[uintptr]bool:
+		var v2 map[uintptr]bool
+		v2, changed = fastpathTV.DecMapUintptrBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]interface{}:
+		fastpathTV.DecMapIntIntfV(v, false, d)
+	case *map[int]interface{}:
+		var v2 map[int]interface{}
+		v2, changed = fastpathTV.DecMapIntIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]string:
+		fastpathTV.DecMapIntStringV(v, false, d)
+	case *map[int]string:
+		var v2 map[int]string
+		v2, changed = fastpathTV.DecMapIntStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uint:
+		fastpathTV.DecMapIntUintV(v, false, d)
+	case *map[int]uint:
+		var v2 map[int]uint
+		v2, changed = fastpathTV.DecMapIntUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uint8:
+		fastpathTV.DecMapIntUint8V(v, false, d)
+	case *map[int]uint8:
+		var v2 map[int]uint8
+		v2, changed = fastpathTV.DecMapIntUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uint16:
+		fastpathTV.DecMapIntUint16V(v, false, d)
+	case *map[int]uint16:
+		var v2 map[int]uint16
+		v2, changed = fastpathTV.DecMapIntUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uint32:
+		fastpathTV.DecMapIntUint32V(v, false, d)
+	case *map[int]uint32:
+		var v2 map[int]uint32
+		v2, changed = fastpathTV.DecMapIntUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uint64:
+		fastpathTV.DecMapIntUint64V(v, false, d)
+	case *map[int]uint64:
+		var v2 map[int]uint64
+		v2, changed = fastpathTV.DecMapIntUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]uintptr:
+		fastpathTV.DecMapIntUintptrV(v, false, d)
+	case *map[int]uintptr:
+		var v2 map[int]uintptr
+		v2, changed = fastpathTV.DecMapIntUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]int:
+		fastpathTV.DecMapIntIntV(v, false, d)
+	case *map[int]int:
+		var v2 map[int]int
+		v2, changed = fastpathTV.DecMapIntIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]int8:
+		fastpathTV.DecMapIntInt8V(v, false, d)
+	case *map[int]int8:
+		var v2 map[int]int8
+		v2, changed = fastpathTV.DecMapIntInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]int16:
+		fastpathTV.DecMapIntInt16V(v, false, d)
+	case *map[int]int16:
+		var v2 map[int]int16
+		v2, changed = fastpathTV.DecMapIntInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]int32:
+		fastpathTV.DecMapIntInt32V(v, false, d)
+	case *map[int]int32:
+		var v2 map[int]int32
+		v2, changed = fastpathTV.DecMapIntInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]int64:
+		fastpathTV.DecMapIntInt64V(v, false, d)
+	case *map[int]int64:
+		var v2 map[int]int64
+		v2, changed = fastpathTV.DecMapIntInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]float32:
+		fastpathTV.DecMapIntFloat32V(v, false, d)
+	case *map[int]float32:
+		var v2 map[int]float32
+		v2, changed = fastpathTV.DecMapIntFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]float64:
+		fastpathTV.DecMapIntFloat64V(v, false, d)
+	case *map[int]float64:
+		var v2 map[int]float64
+		v2, changed = fastpathTV.DecMapIntFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int]bool:
+		fastpathTV.DecMapIntBoolV(v, false, d)
+	case *map[int]bool:
+		var v2 map[int]bool
+		v2, changed = fastpathTV.DecMapIntBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]interface{}:
+		fastpathTV.DecMapInt8IntfV(v, false, d)
+	case *map[int8]interface{}:
+		var v2 map[int8]interface{}
+		v2, changed = fastpathTV.DecMapInt8IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]string:
+		fastpathTV.DecMapInt8StringV(v, false, d)
+	case *map[int8]string:
+		var v2 map[int8]string
+		v2, changed = fastpathTV.DecMapInt8StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uint:
+		fastpathTV.DecMapInt8UintV(v, false, d)
+	case *map[int8]uint:
+		var v2 map[int8]uint
+		v2, changed = fastpathTV.DecMapInt8UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uint8:
+		fastpathTV.DecMapInt8Uint8V(v, false, d)
+	case *map[int8]uint8:
+		var v2 map[int8]uint8
+		v2, changed = fastpathTV.DecMapInt8Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uint16:
+		fastpathTV.DecMapInt8Uint16V(v, false, d)
+	case *map[int8]uint16:
+		var v2 map[int8]uint16
+		v2, changed = fastpathTV.DecMapInt8Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uint32:
+		fastpathTV.DecMapInt8Uint32V(v, false, d)
+	case *map[int8]uint32:
+		var v2 map[int8]uint32
+		v2, changed = fastpathTV.DecMapInt8Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uint64:
+		fastpathTV.DecMapInt8Uint64V(v, false, d)
+	case *map[int8]uint64:
+		var v2 map[int8]uint64
+		v2, changed = fastpathTV.DecMapInt8Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]uintptr:
+		fastpathTV.DecMapInt8UintptrV(v, false, d)
+	case *map[int8]uintptr:
+		var v2 map[int8]uintptr
+		v2, changed = fastpathTV.DecMapInt8UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]int:
+		fastpathTV.DecMapInt8IntV(v, false, d)
+	case *map[int8]int:
+		var v2 map[int8]int
+		v2, changed = fastpathTV.DecMapInt8IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]int8:
+		fastpathTV.DecMapInt8Int8V(v, false, d)
+	case *map[int8]int8:
+		var v2 map[int8]int8
+		v2, changed = fastpathTV.DecMapInt8Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]int16:
+		fastpathTV.DecMapInt8Int16V(v, false, d)
+	case *map[int8]int16:
+		var v2 map[int8]int16
+		v2, changed = fastpathTV.DecMapInt8Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]int32:
+		fastpathTV.DecMapInt8Int32V(v, false, d)
+	case *map[int8]int32:
+		var v2 map[int8]int32
+		v2, changed = fastpathTV.DecMapInt8Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]int64:
+		fastpathTV.DecMapInt8Int64V(v, false, d)
+	case *map[int8]int64:
+		var v2 map[int8]int64
+		v2, changed = fastpathTV.DecMapInt8Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]float32:
+		fastpathTV.DecMapInt8Float32V(v, false, d)
+	case *map[int8]float32:
+		var v2 map[int8]float32
+		v2, changed = fastpathTV.DecMapInt8Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]float64:
+		fastpathTV.DecMapInt8Float64V(v, false, d)
+	case *map[int8]float64:
+		var v2 map[int8]float64
+		v2, changed = fastpathTV.DecMapInt8Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int8]bool:
+		fastpathTV.DecMapInt8BoolV(v, false, d)
+	case *map[int8]bool:
+		var v2 map[int8]bool
+		v2, changed = fastpathTV.DecMapInt8BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]interface{}:
+		fastpathTV.DecMapInt16IntfV(v, false, d)
+	case *map[int16]interface{}:
+		var v2 map[int16]interface{}
+		v2, changed = fastpathTV.DecMapInt16IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]string:
+		fastpathTV.DecMapInt16StringV(v, false, d)
+	case *map[int16]string:
+		var v2 map[int16]string
+		v2, changed = fastpathTV.DecMapInt16StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uint:
+		fastpathTV.DecMapInt16UintV(v, false, d)
+	case *map[int16]uint:
+		var v2 map[int16]uint
+		v2, changed = fastpathTV.DecMapInt16UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uint8:
+		fastpathTV.DecMapInt16Uint8V(v, false, d)
+	case *map[int16]uint8:
+		var v2 map[int16]uint8
+		v2, changed = fastpathTV.DecMapInt16Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uint16:
+		fastpathTV.DecMapInt16Uint16V(v, false, d)
+	case *map[int16]uint16:
+		var v2 map[int16]uint16
+		v2, changed = fastpathTV.DecMapInt16Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uint32:
+		fastpathTV.DecMapInt16Uint32V(v, false, d)
+	case *map[int16]uint32:
+		var v2 map[int16]uint32
+		v2, changed = fastpathTV.DecMapInt16Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uint64:
+		fastpathTV.DecMapInt16Uint64V(v, false, d)
+	case *map[int16]uint64:
+		var v2 map[int16]uint64
+		v2, changed = fastpathTV.DecMapInt16Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]uintptr:
+		fastpathTV.DecMapInt16UintptrV(v, false, d)
+	case *map[int16]uintptr:
+		var v2 map[int16]uintptr
+		v2, changed = fastpathTV.DecMapInt16UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]int:
+		fastpathTV.DecMapInt16IntV(v, false, d)
+	case *map[int16]int:
+		var v2 map[int16]int
+		v2, changed = fastpathTV.DecMapInt16IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]int8:
+		fastpathTV.DecMapInt16Int8V(v, false, d)
+	case *map[int16]int8:
+		var v2 map[int16]int8
+		v2, changed = fastpathTV.DecMapInt16Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]int16:
+		fastpathTV.DecMapInt16Int16V(v, false, d)
+	case *map[int16]int16:
+		var v2 map[int16]int16
+		v2, changed = fastpathTV.DecMapInt16Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]int32:
+		fastpathTV.DecMapInt16Int32V(v, false, d)
+	case *map[int16]int32:
+		var v2 map[int16]int32
+		v2, changed = fastpathTV.DecMapInt16Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]int64:
+		fastpathTV.DecMapInt16Int64V(v, false, d)
+	case *map[int16]int64:
+		var v2 map[int16]int64
+		v2, changed = fastpathTV.DecMapInt16Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]float32:
+		fastpathTV.DecMapInt16Float32V(v, false, d)
+	case *map[int16]float32:
+		var v2 map[int16]float32
+		v2, changed = fastpathTV.DecMapInt16Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]float64:
+		fastpathTV.DecMapInt16Float64V(v, false, d)
+	case *map[int16]float64:
+		var v2 map[int16]float64
+		v2, changed = fastpathTV.DecMapInt16Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int16]bool:
+		fastpathTV.DecMapInt16BoolV(v, false, d)
+	case *map[int16]bool:
+		var v2 map[int16]bool
+		v2, changed = fastpathTV.DecMapInt16BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]interface{}:
+		fastpathTV.DecMapInt32IntfV(v, false, d)
+	case *map[int32]interface{}:
+		var v2 map[int32]interface{}
+		v2, changed = fastpathTV.DecMapInt32IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]string:
+		fastpathTV.DecMapInt32StringV(v, false, d)
+	case *map[int32]string:
+		var v2 map[int32]string
+		v2, changed = fastpathTV.DecMapInt32StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uint:
+		fastpathTV.DecMapInt32UintV(v, false, d)
+	case *map[int32]uint:
+		var v2 map[int32]uint
+		v2, changed = fastpathTV.DecMapInt32UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uint8:
+		fastpathTV.DecMapInt32Uint8V(v, false, d)
+	case *map[int32]uint8:
+		var v2 map[int32]uint8
+		v2, changed = fastpathTV.DecMapInt32Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uint16:
+		fastpathTV.DecMapInt32Uint16V(v, false, d)
+	case *map[int32]uint16:
+		var v2 map[int32]uint16
+		v2, changed = fastpathTV.DecMapInt32Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uint32:
+		fastpathTV.DecMapInt32Uint32V(v, false, d)
+	case *map[int32]uint32:
+		var v2 map[int32]uint32
+		v2, changed = fastpathTV.DecMapInt32Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uint64:
+		fastpathTV.DecMapInt32Uint64V(v, false, d)
+	case *map[int32]uint64:
+		var v2 map[int32]uint64
+		v2, changed = fastpathTV.DecMapInt32Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]uintptr:
+		fastpathTV.DecMapInt32UintptrV(v, false, d)
+	case *map[int32]uintptr:
+		var v2 map[int32]uintptr
+		v2, changed = fastpathTV.DecMapInt32UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]int:
+		fastpathTV.DecMapInt32IntV(v, false, d)
+	case *map[int32]int:
+		var v2 map[int32]int
+		v2, changed = fastpathTV.DecMapInt32IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]int8:
+		fastpathTV.DecMapInt32Int8V(v, false, d)
+	case *map[int32]int8:
+		var v2 map[int32]int8
+		v2, changed = fastpathTV.DecMapInt32Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]int16:
+		fastpathTV.DecMapInt32Int16V(v, false, d)
+	case *map[int32]int16:
+		var v2 map[int32]int16
+		v2, changed = fastpathTV.DecMapInt32Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]int32:
+		fastpathTV.DecMapInt32Int32V(v, false, d)
+	case *map[int32]int32:
+		var v2 map[int32]int32
+		v2, changed = fastpathTV.DecMapInt32Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]int64:
+		fastpathTV.DecMapInt32Int64V(v, false, d)
+	case *map[int32]int64:
+		var v2 map[int32]int64
+		v2, changed = fastpathTV.DecMapInt32Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]float32:
+		fastpathTV.DecMapInt32Float32V(v, false, d)
+	case *map[int32]float32:
+		var v2 map[int32]float32
+		v2, changed = fastpathTV.DecMapInt32Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]float64:
+		fastpathTV.DecMapInt32Float64V(v, false, d)
+	case *map[int32]float64:
+		var v2 map[int32]float64
+		v2, changed = fastpathTV.DecMapInt32Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int32]bool:
+		fastpathTV.DecMapInt32BoolV(v, false, d)
+	case *map[int32]bool:
+		var v2 map[int32]bool
+		v2, changed = fastpathTV.DecMapInt32BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]interface{}:
+		fastpathTV.DecMapInt64IntfV(v, false, d)
+	case *map[int64]interface{}:
+		var v2 map[int64]interface{}
+		v2, changed = fastpathTV.DecMapInt64IntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]string:
+		fastpathTV.DecMapInt64StringV(v, false, d)
+	case *map[int64]string:
+		var v2 map[int64]string
+		v2, changed = fastpathTV.DecMapInt64StringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uint:
+		fastpathTV.DecMapInt64UintV(v, false, d)
+	case *map[int64]uint:
+		var v2 map[int64]uint
+		v2, changed = fastpathTV.DecMapInt64UintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uint8:
+		fastpathTV.DecMapInt64Uint8V(v, false, d)
+	case *map[int64]uint8:
+		var v2 map[int64]uint8
+		v2, changed = fastpathTV.DecMapInt64Uint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uint16:
+		fastpathTV.DecMapInt64Uint16V(v, false, d)
+	case *map[int64]uint16:
+		var v2 map[int64]uint16
+		v2, changed = fastpathTV.DecMapInt64Uint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uint32:
+		fastpathTV.DecMapInt64Uint32V(v, false, d)
+	case *map[int64]uint32:
+		var v2 map[int64]uint32
+		v2, changed = fastpathTV.DecMapInt64Uint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uint64:
+		fastpathTV.DecMapInt64Uint64V(v, false, d)
+	case *map[int64]uint64:
+		var v2 map[int64]uint64
+		v2, changed = fastpathTV.DecMapInt64Uint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]uintptr:
+		fastpathTV.DecMapInt64UintptrV(v, false, d)
+	case *map[int64]uintptr:
+		var v2 map[int64]uintptr
+		v2, changed = fastpathTV.DecMapInt64UintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]int:
+		fastpathTV.DecMapInt64IntV(v, false, d)
+	case *map[int64]int:
+		var v2 map[int64]int
+		v2, changed = fastpathTV.DecMapInt64IntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]int8:
+		fastpathTV.DecMapInt64Int8V(v, false, d)
+	case *map[int64]int8:
+		var v2 map[int64]int8
+		v2, changed = fastpathTV.DecMapInt64Int8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]int16:
+		fastpathTV.DecMapInt64Int16V(v, false, d)
+	case *map[int64]int16:
+		var v2 map[int64]int16
+		v2, changed = fastpathTV.DecMapInt64Int16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]int32:
+		fastpathTV.DecMapInt64Int32V(v, false, d)
+	case *map[int64]int32:
+		var v2 map[int64]int32
+		v2, changed = fastpathTV.DecMapInt64Int32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]int64:
+		fastpathTV.DecMapInt64Int64V(v, false, d)
+	case *map[int64]int64:
+		var v2 map[int64]int64
+		v2, changed = fastpathTV.DecMapInt64Int64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]float32:
+		fastpathTV.DecMapInt64Float32V(v, false, d)
+	case *map[int64]float32:
+		var v2 map[int64]float32
+		v2, changed = fastpathTV.DecMapInt64Float32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]float64:
+		fastpathTV.DecMapInt64Float64V(v, false, d)
+	case *map[int64]float64:
+		var v2 map[int64]float64
+		v2, changed = fastpathTV.DecMapInt64Float64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[int64]bool:
+		fastpathTV.DecMapInt64BoolV(v, false, d)
+	case *map[int64]bool:
+		var v2 map[int64]bool
+		v2, changed = fastpathTV.DecMapInt64BoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]interface{}:
+		fastpathTV.DecMapBoolIntfV(v, false, d)
+	case *map[bool]interface{}:
+		var v2 map[bool]interface{}
+		v2, changed = fastpathTV.DecMapBoolIntfV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]string:
+		fastpathTV.DecMapBoolStringV(v, false, d)
+	case *map[bool]string:
+		var v2 map[bool]string
+		v2, changed = fastpathTV.DecMapBoolStringV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uint:
+		fastpathTV.DecMapBoolUintV(v, false, d)
+	case *map[bool]uint:
+		var v2 map[bool]uint
+		v2, changed = fastpathTV.DecMapBoolUintV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uint8:
+		fastpathTV.DecMapBoolUint8V(v, false, d)
+	case *map[bool]uint8:
+		var v2 map[bool]uint8
+		v2, changed = fastpathTV.DecMapBoolUint8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uint16:
+		fastpathTV.DecMapBoolUint16V(v, false, d)
+	case *map[bool]uint16:
+		var v2 map[bool]uint16
+		v2, changed = fastpathTV.DecMapBoolUint16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uint32:
+		fastpathTV.DecMapBoolUint32V(v, false, d)
+	case *map[bool]uint32:
+		var v2 map[bool]uint32
+		v2, changed = fastpathTV.DecMapBoolUint32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uint64:
+		fastpathTV.DecMapBoolUint64V(v, false, d)
+	case *map[bool]uint64:
+		var v2 map[bool]uint64
+		v2, changed = fastpathTV.DecMapBoolUint64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]uintptr:
+		fastpathTV.DecMapBoolUintptrV(v, false, d)
+	case *map[bool]uintptr:
+		var v2 map[bool]uintptr
+		v2, changed = fastpathTV.DecMapBoolUintptrV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]int:
+		fastpathTV.DecMapBoolIntV(v, false, d)
+	case *map[bool]int:
+		var v2 map[bool]int
+		v2, changed = fastpathTV.DecMapBoolIntV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]int8:
+		fastpathTV.DecMapBoolInt8V(v, false, d)
+	case *map[bool]int8:
+		var v2 map[bool]int8
+		v2, changed = fastpathTV.DecMapBoolInt8V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]int16:
+		fastpathTV.DecMapBoolInt16V(v, false, d)
+	case *map[bool]int16:
+		var v2 map[bool]int16
+		v2, changed = fastpathTV.DecMapBoolInt16V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]int32:
+		fastpathTV.DecMapBoolInt32V(v, false, d)
+	case *map[bool]int32:
+		var v2 map[bool]int32
+		v2, changed = fastpathTV.DecMapBoolInt32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]int64:
+		fastpathTV.DecMapBoolInt64V(v, false, d)
+	case *map[bool]int64:
+		var v2 map[bool]int64
+		v2, changed = fastpathTV.DecMapBoolInt64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]float32:
+		fastpathTV.DecMapBoolFloat32V(v, false, d)
+	case *map[bool]float32:
+		var v2 map[bool]float32
+		v2, changed = fastpathTV.DecMapBoolFloat32V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]float64:
+		fastpathTV.DecMapBoolFloat64V(v, false, d)
+	case *map[bool]float64:
+		var v2 map[bool]float64
+		v2, changed = fastpathTV.DecMapBoolFloat64V(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	case map[bool]bool:
+		fastpathTV.DecMapBoolBoolV(v, false, d)
+	case *map[bool]bool:
+		var v2 map[bool]bool
+		v2, changed = fastpathTV.DecMapBoolBoolV(*v, true, d)
+		if changed {
+			*v = v2
+		}
+	default:
+		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
+	switch v := iv.(type) {
+
+	case *[]interface{}:
+		*v = nil
+	case *[]string:
+		*v = nil
+	case *[]float32:
+		*v = nil
+	case *[]float64:
+		*v = nil
+	case *[]uint:
+		*v = nil
+	case *[]uint8:
+		*v = nil
+	case *[]uint16:
+		*v = nil
+	case *[]uint32:
+		*v = nil
+	case *[]uint64:
+		*v = nil
+	case *[]uintptr:
+		*v = nil
+	case *[]int:
+		*v = nil
+	case *[]int8:
+		*v = nil
+	case *[]int16:
+		*v = nil
+	case *[]int32:
+		*v = nil
+	case *[]int64:
+		*v = nil
+	case *[]bool:
+		*v = nil
+
+	case *map[interface{}]interface{}:
+		*v = nil
+	case *map[interface{}]string:
+		*v = nil
+	case *map[interface{}]uint:
+		*v = nil
+	case *map[interface{}]uint8:
+		*v = nil
+	case *map[interface{}]uint16:
+		*v = nil
+	case *map[interface{}]uint32:
+		*v = nil
+	case *map[interface{}]uint64:
+		*v = nil
+	case *map[interface{}]uintptr:
+		*v = nil
+	case *map[interface{}]int:
+		*v = nil
+	case *map[interface{}]int8:
+		*v = nil
+	case *map[interface{}]int16:
+		*v = nil
+	case *map[interface{}]int32:
+		*v = nil
+	case *map[interface{}]int64:
+		*v = nil
+	case *map[interface{}]float32:
+		*v = nil
+	case *map[interface{}]float64:
+		*v = nil
+	case *map[interface{}]bool:
+		*v = nil
+	case *map[string]interface{}:
+		*v = nil
+	case *map[string]string:
+		*v = nil
+	case *map[string]uint:
+		*v = nil
+	case *map[string]uint8:
+		*v = nil
+	case *map[string]uint16:
+		*v = nil
+	case *map[string]uint32:
+		*v = nil
+	case *map[string]uint64:
+		*v = nil
+	case *map[string]uintptr:
+		*v = nil
+	case *map[string]int:
+		*v = nil
+	case *map[string]int8:
+		*v = nil
+	case *map[string]int16:
+		*v = nil
+	case *map[string]int32:
+		*v = nil
+	case *map[string]int64:
+		*v = nil
+	case *map[string]float32:
+		*v = nil
+	case *map[string]float64:
+		*v = nil
+	case *map[string]bool:
+		*v = nil
+	case *map[float32]interface{}:
+		*v = nil
+	case *map[float32]string:
+		*v = nil
+	case *map[float32]uint:
+		*v = nil
+	case *map[float32]uint8:
+		*v = nil
+	case *map[float32]uint16:
+		*v = nil
+	case *map[float32]uint32:
+		*v = nil
+	case *map[float32]uint64:
+		*v = nil
+	case *map[float32]uintptr:
+		*v = nil
+	case *map[float32]int:
+		*v = nil
+	case *map[float32]int8:
+		*v = nil
+	case *map[float32]int16:
+		*v = nil
+	case *map[float32]int32:
+		*v = nil
+	case *map[float32]int64:
+		*v = nil
+	case *map[float32]float32:
+		*v = nil
+	case *map[float32]float64:
+		*v = nil
+	case *map[float32]bool:
+		*v = nil
+	case *map[float64]interface{}:
+		*v = nil
+	case *map[float64]string:
+		*v = nil
+	case *map[float64]uint:
+		*v = nil
+	case *map[float64]uint8:
+		*v = nil
+	case *map[float64]uint16:
+		*v = nil
+	case *map[float64]uint32:
+		*v = nil
+	case *map[float64]uint64:
+		*v = nil
+	case *map[float64]uintptr:
+		*v = nil
+	case *map[float64]int:
+		*v = nil
+	case *map[float64]int8:
+		*v = nil
+	case *map[float64]int16:
+		*v = nil
+	case *map[float64]int32:
+		*v = nil
+	case *map[float64]int64:
+		*v = nil
+	case *map[float64]float32:
+		*v = nil
+	case *map[float64]float64:
+		*v = nil
+	case *map[float64]bool:
+		*v = nil
+	case *map[uint]interface{}:
+		*v = nil
+	case *map[uint]string:
+		*v = nil
+	case *map[uint]uint:
+		*v = nil
+	case *map[uint]uint8:
+		*v = nil
+	case *map[uint]uint16:
+		*v = nil
+	case *map[uint]uint32:
+		*v = nil
+	case *map[uint]uint64:
+		*v = nil
+	case *map[uint]uintptr:
+		*v = nil
+	case *map[uint]int:
+		*v = nil
+	case *map[uint]int8:
+		*v = nil
+	case *map[uint]int16:
+		*v = nil
+	case *map[uint]int32:
+		*v = nil
+	case *map[uint]int64:
+		*v = nil
+	case *map[uint]float32:
+		*v = nil
+	case *map[uint]float64:
+		*v = nil
+	case *map[uint]bool:
+		*v = nil
+	case *map[uint8]interface{}:
+		*v = nil
+	case *map[uint8]string:
+		*v = nil
+	case *map[uint8]uint:
+		*v = nil
+	case *map[uint8]uint8:
+		*v = nil
+	case *map[uint8]uint16:
+		*v = nil
+	case *map[uint8]uint32:
+		*v = nil
+	case *map[uint8]uint64:
+		*v = nil
+	case *map[uint8]uintptr:
+		*v = nil
+	case *map[uint8]int:
+		*v = nil
+	case *map[uint8]int8:
+		*v = nil
+	case *map[uint8]int16:
+		*v = nil
+	case *map[uint8]int32:
+		*v = nil
+	case *map[uint8]int64:
+		*v = nil
+	case *map[uint8]float32:
+		*v = nil
+	case *map[uint8]float64:
+		*v = nil
+	case *map[uint8]bool:
+		*v = nil
+	case *map[uint16]interface{}:
+		*v = nil
+	case *map[uint16]string:
+		*v = nil
+	case *map[uint16]uint:
+		*v = nil
+	case *map[uint16]uint8:
+		*v = nil
+	case *map[uint16]uint16:
+		*v = nil
+	case *map[uint16]uint32:
+		*v = nil
+	case *map[uint16]uint64:
+		*v = nil
+	case *map[uint16]uintptr:
+		*v = nil
+	case *map[uint16]int:
+		*v = nil
+	case *map[uint16]int8:
+		*v = nil
+	case *map[uint16]int16:
+		*v = nil
+	case *map[uint16]int32:
+		*v = nil
+	case *map[uint16]int64:
+		*v = nil
+	case *map[uint16]float32:
+		*v = nil
+	case *map[uint16]float64:
+		*v = nil
+	case *map[uint16]bool:
+		*v = nil
+	case *map[uint32]interface{}:
+		*v = nil
+	case *map[uint32]string:
+		*v = nil
+	case *map[uint32]uint:
+		*v = nil
+	case *map[uint32]uint8:
+		*v = nil
+	case *map[uint32]uint16:
+		*v = nil
+	case *map[uint32]uint32:
+		*v = nil
+	case *map[uint32]uint64:
+		*v = nil
+	case *map[uint32]uintptr:
+		*v = nil
+	case *map[uint32]int:
+		*v = nil
+	case *map[uint32]int8:
+		*v = nil
+	case *map[uint32]int16:
+		*v = nil
+	case *map[uint32]int32:
+		*v = nil
+	case *map[uint32]int64:
+		*v = nil
+	case *map[uint32]float32:
+		*v = nil
+	case *map[uint32]float64:
+		*v = nil
+	case *map[uint32]bool:
+		*v = nil
+	case *map[uint64]interface{}:
+		*v = nil
+	case *map[uint64]string:
+		*v = nil
+	case *map[uint64]uint:
+		*v = nil
+	case *map[uint64]uint8:
+		*v = nil
+	case *map[uint64]uint16:
+		*v = nil
+	case *map[uint64]uint32:
+		*v = nil
+	case *map[uint64]uint64:
+		*v = nil
+	case *map[uint64]uintptr:
+		*v = nil
+	case *map[uint64]int:
+		*v = nil
+	case *map[uint64]int8:
+		*v = nil
+	case *map[uint64]int16:
+		*v = nil
+	case *map[uint64]int32:
+		*v = nil
+	case *map[uint64]int64:
+		*v = nil
+	case *map[uint64]float32:
+		*v = nil
+	case *map[uint64]float64:
+		*v = nil
+	case *map[uint64]bool:
+		*v = nil
+	case *map[uintptr]interface{}:
+		*v = nil
+	case *map[uintptr]string:
+		*v = nil
+	case *map[uintptr]uint:
+		*v = nil
+	case *map[uintptr]uint8:
+		*v = nil
+	case *map[uintptr]uint16:
+		*v = nil
+	case *map[uintptr]uint32:
+		*v = nil
+	case *map[uintptr]uint64:
+		*v = nil
+	case *map[uintptr]uintptr:
+		*v = nil
+	case *map[uintptr]int:
+		*v = nil
+	case *map[uintptr]int8:
+		*v = nil
+	case *map[uintptr]int16:
+		*v = nil
+	case *map[uintptr]int32:
+		*v = nil
+	case *map[uintptr]int64:
+		*v = nil
+	case *map[uintptr]float32:
+		*v = nil
+	case *map[uintptr]float64:
+		*v = nil
+	case *map[uintptr]bool:
+		*v = nil
+	case *map[int]interface{}:
+		*v = nil
+	case *map[int]string:
+		*v = nil
+	case *map[int]uint:
+		*v = nil
+	case *map[int]uint8:
+		*v = nil
+	case *map[int]uint16:
+		*v = nil
+	case *map[int]uint32:
+		*v = nil
+	case *map[int]uint64:
+		*v = nil
+	case *map[int]uintptr:
+		*v = nil
+	case *map[int]int:
+		*v = nil
+	case *map[int]int8:
+		*v = nil
+	case *map[int]int16:
+		*v = nil
+	case *map[int]int32:
+		*v = nil
+	case *map[int]int64:
+		*v = nil
+	case *map[int]float32:
+		*v = nil
+	case *map[int]float64:
+		*v = nil
+	case *map[int]bool:
+		*v = nil
+	case *map[int8]interface{}:
+		*v = nil
+	case *map[int8]string:
+		*v = nil
+	case *map[int8]uint:
+		*v = nil
+	case *map[int8]uint8:
+		*v = nil
+	case *map[int8]uint16:
+		*v = nil
+	case *map[int8]uint32:
+		*v = nil
+	case *map[int8]uint64:
+		*v = nil
+	case *map[int8]uintptr:
+		*v = nil
+	case *map[int8]int:
+		*v = nil
+	case *map[int8]int8:
+		*v = nil
+	case *map[int8]int16:
+		*v = nil
+	case *map[int8]int32:
+		*v = nil
+	case *map[int8]int64:
+		*v = nil
+	case *map[int8]float32:
+		*v = nil
+	case *map[int8]float64:
+		*v = nil
+	case *map[int8]bool:
+		*v = nil
+	case *map[int16]interface{}:
+		*v = nil
+	case *map[int16]string:
+		*v = nil
+	case *map[int16]uint:
+		*v = nil
+	case *map[int16]uint8:
+		*v = nil
+	case *map[int16]uint16:
+		*v = nil
+	case *map[int16]uint32:
+		*v = nil
+	case *map[int16]uint64:
+		*v = nil
+	case *map[int16]uintptr:
+		*v = nil
+	case *map[int16]int:
+		*v = nil
+	case *map[int16]int8:
+		*v = nil
+	case *map[int16]int16:
+		*v = nil
+	case *map[int16]int32:
+		*v = nil
+	case *map[int16]int64:
+		*v = nil
+	case *map[int16]float32:
+		*v = nil
+	case *map[int16]float64:
+		*v = nil
+	case *map[int16]bool:
+		*v = nil
+	case *map[int32]interface{}:
+		*v = nil
+	case *map[int32]string:
+		*v = nil
+	case *map[int32]uint:
+		*v = nil
+	case *map[int32]uint8:
+		*v = nil
+	case *map[int32]uint16:
+		*v = nil
+	case *map[int32]uint32:
+		*v = nil
+	case *map[int32]uint64:
+		*v = nil
+	case *map[int32]uintptr:
+		*v = nil
+	case *map[int32]int:
+		*v = nil
+	case *map[int32]int8:
+		*v = nil
+	case *map[int32]int16:
+		*v = nil
+	case *map[int32]int32:
+		*v = nil
+	case *map[int32]int64:
+		*v = nil
+	case *map[int32]float32:
+		*v = nil
+	case *map[int32]float64:
+		*v = nil
+	case *map[int32]bool:
+		*v = nil
+	case *map[int64]interface{}:
+		*v = nil
+	case *map[int64]string:
+		*v = nil
+	case *map[int64]uint:
+		*v = nil
+	case *map[int64]uint8:
+		*v = nil
+	case *map[int64]uint16:
+		*v = nil
+	case *map[int64]uint32:
+		*v = nil
+	case *map[int64]uint64:
+		*v = nil
+	case *map[int64]uintptr:
+		*v = nil
+	case *map[int64]int:
+		*v = nil
+	case *map[int64]int8:
+		*v = nil
+	case *map[int64]int16:
+		*v = nil
+	case *map[int64]int32:
+		*v = nil
+	case *map[int64]int64:
+		*v = nil
+	case *map[int64]float32:
+		*v = nil
+	case *map[int64]float64:
+		*v = nil
+	case *map[int64]bool:
+		*v = nil
+	case *map[bool]interface{}:
+		*v = nil
+	case *map[bool]string:
+		*v = nil
+	case *map[bool]uint:
+		*v = nil
+	case *map[bool]uint8:
+		*v = nil
+	case *map[bool]uint16:
+		*v = nil
+	case *map[bool]uint32:
+		*v = nil
+	case *map[bool]uint64:
+		*v = nil
+	case *map[bool]uintptr:
+		*v = nil
+	case *map[bool]int:
+		*v = nil
+	case *map[bool]int8:
+		*v = nil
+	case *map[bool]int16:
+		*v = nil
+	case *map[bool]int32:
+		*v = nil
+	case *map[bool]int64:
+		*v = nil
+	case *map[bool]float32:
+		*v = nil
+	case *map[bool]float64:
+		*v = nil
+	case *map[bool]bool:
+		*v = nil
+	default:
+		_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+// -- -- fast path functions
+
+func (d *Decoder) fastpathDecSliceIntfR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]interface{})
+		v, changed := fastpathTV.DecSliceIntfV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]interface{})
+		v2, changed := fastpathTV.DecSliceIntfV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceIntfX(vp *[]interface{}, d *Decoder) {
+	v, changed := f.DecSliceIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceIntfV(v []interface{}, canChange bool, d *Decoder) (_ []interface{}, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []interface{}{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]interface{}, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+			} else {
+				xlen = 8
+			}
+			v = make([]interface{}, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, nil)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = nil
+		} else {
+			d.decode(&v[j])
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]interface{}, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceStringR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]string)
+		v, changed := fastpathTV.DecSliceStringV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]string)
+		v2, changed := fastpathTV.DecSliceStringV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceStringX(vp *[]string, d *Decoder) {
+	v, changed := f.DecSliceStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceStringV(v []string, canChange bool, d *Decoder) (_ []string, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []string{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]string, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 16)
+			} else {
+				xlen = 8
+			}
+			v = make([]string, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, "")
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = ""
+		} else {
+			v[j] = dd.DecodeString()
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]string, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]float32)
+		v, changed := fastpathTV.DecSliceFloat32V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]float32)
+		v2, changed := fastpathTV.DecSliceFloat32V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceFloat32X(vp *[]float32, d *Decoder) {
+	v, changed := f.DecSliceFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceFloat32V(v []float32, canChange bool, d *Decoder) (_ []float32, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []float32{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]float32, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			} else {
+				xlen = 8
+			}
+			v = make([]float32, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]float32, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]float64)
+		v, changed := fastpathTV.DecSliceFloat64V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]float64)
+		v2, changed := fastpathTV.DecSliceFloat64V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceFloat64X(vp *[]float64, d *Decoder) {
+	v, changed := f.DecSliceFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceFloat64V(v []float64, canChange bool, d *Decoder) (_ []float64, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []float64{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]float64, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]float64, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = dd.DecodeFloat64()
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]float64, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUintR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uint)
+		v, changed := fastpathTV.DecSliceUintV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uint)
+		v2, changed := fastpathTV.DecSliceUintV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUintX(vp *[]uint, d *Decoder) {
+	v, changed := f.DecSliceUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUintV(v []uint, canChange bool, d *Decoder) (_ []uint, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uint{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uint, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]uint, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uint, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUint8R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uint8)
+		v, changed := fastpathTV.DecSliceUint8V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uint8)
+		v2, changed := fastpathTV.DecSliceUint8V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUint8X(vp *[]uint8, d *Decoder) {
+	v, changed := f.DecSliceUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uint8{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uint8, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			} else {
+				xlen = 8
+			}
+			v = make([]uint8, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uint8, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUint16R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uint16)
+		v, changed := fastpathTV.DecSliceUint16V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uint16)
+		v2, changed := fastpathTV.DecSliceUint16V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUint16X(vp *[]uint16, d *Decoder) {
+	v, changed := f.DecSliceUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUint16V(v []uint16, canChange bool, d *Decoder) (_ []uint16, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uint16{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uint16, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+			} else {
+				xlen = 8
+			}
+			v = make([]uint16, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uint16, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUint32R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uint32)
+		v, changed := fastpathTV.DecSliceUint32V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uint32)
+		v2, changed := fastpathTV.DecSliceUint32V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUint32X(vp *[]uint32, d *Decoder) {
+	v, changed := f.DecSliceUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUint32V(v []uint32, canChange bool, d *Decoder) (_ []uint32, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uint32{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uint32, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			} else {
+				xlen = 8
+			}
+			v = make([]uint32, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uint32, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUint64R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uint64)
+		v, changed := fastpathTV.DecSliceUint64V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uint64)
+		v2, changed := fastpathTV.DecSliceUint64V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUint64X(vp *[]uint64, d *Decoder) {
+	v, changed := f.DecSliceUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUint64V(v []uint64, canChange bool, d *Decoder) (_ []uint64, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uint64{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uint64, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]uint64, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = dd.DecodeUint64()
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uint64, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]uintptr)
+		v, changed := fastpathTV.DecSliceUintptrV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]uintptr)
+		v2, changed := fastpathTV.DecSliceUintptrV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceUintptrX(vp *[]uintptr, d *Decoder) {
+	v, changed := f.DecSliceUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceUintptrV(v []uintptr, canChange bool, d *Decoder) (_ []uintptr, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []uintptr{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]uintptr, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]uintptr, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]uintptr, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceIntR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]int)
+		v, changed := fastpathTV.DecSliceIntV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]int)
+		v2, changed := fastpathTV.DecSliceIntV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceIntX(vp *[]int, d *Decoder) {
+	v, changed := f.DecSliceIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceIntV(v []int, canChange bool, d *Decoder) (_ []int, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []int{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]int, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]int, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]int, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceInt8R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]int8)
+		v, changed := fastpathTV.DecSliceInt8V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]int8)
+		v2, changed := fastpathTV.DecSliceInt8V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceInt8X(vp *[]int8, d *Decoder) {
+	v, changed := f.DecSliceInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceInt8V(v []int8, canChange bool, d *Decoder) (_ []int8, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []int8{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]int8, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			} else {
+				xlen = 8
+			}
+			v = make([]int8, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]int8, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceInt16R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]int16)
+		v, changed := fastpathTV.DecSliceInt16V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]int16)
+		v2, changed := fastpathTV.DecSliceInt16V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceInt16X(vp *[]int16, d *Decoder) {
+	v, changed := f.DecSliceInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceInt16V(v []int16, canChange bool, d *Decoder) (_ []int16, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []int16{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]int16, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 2)
+			} else {
+				xlen = 8
+			}
+			v = make([]int16, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]int16, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceInt32R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]int32)
+		v, changed := fastpathTV.DecSliceInt32V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]int32)
+		v2, changed := fastpathTV.DecSliceInt32V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceInt32X(vp *[]int32, d *Decoder) {
+	v, changed := f.DecSliceInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceInt32V(v []int32, canChange bool, d *Decoder) (_ []int32, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []int32{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]int32, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 4)
+			} else {
+				xlen = 8
+			}
+			v = make([]int32, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]int32, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceInt64R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]int64)
+		v, changed := fastpathTV.DecSliceInt64V(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]int64)
+		v2, changed := fastpathTV.DecSliceInt64V(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceInt64X(vp *[]int64, d *Decoder) {
+	v, changed := f.DecSliceInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceInt64V(v []int64, canChange bool, d *Decoder) (_ []int64, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []int64{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]int64, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 8)
+			} else {
+				xlen = 8
+			}
+			v = make([]int64, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, 0)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = 0
+		} else {
+			v[j] = dd.DecodeInt64()
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]int64, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecSliceBoolR(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]bool)
+		v, changed := fastpathTV.DecSliceBoolV(*vp, !array, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		v := rv2i(rv).([]bool)
+		v2, changed := fastpathTV.DecSliceBoolV(v, !array, d)
+		if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	}
+}
+func (f fastpathT) DecSliceBoolX(vp *[]bool, d *Decoder) {
+	v, changed := f.DecSliceBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecSliceBoolV(v []bool, canChange bool, d *Decoder) (_ []bool, changed bool) {
+	dd := d.d
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil {
+				v = []bool{}
+			} else if len(v) != 0 {
+				v = v[:0]
+			}
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]bool, xlen)
+			}
+			changed = true
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, 1)
+			} else {
+				xlen = 8
+			}
+			v = make([]bool, xlen)
+			changed = true
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, false)
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		}
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = false
+		} else {
+			v[j] = dd.DecodeBool()
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]bool, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]interface{})
+		v, changed := fastpathTV.DecMapIntfIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfIntfV(rv2i(rv).(map[interface{}]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, d *Decoder) {
+	v, changed := f.DecMapIntfIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, canChange bool,
+	d *Decoder) (_ map[interface{}]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		v = make(map[interface{}]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk interface{}
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]string)
+		v, changed := fastpathTV.DecMapIntfStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfStringV(rv2i(rv).(map[interface{}]string), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, d *Decoder) {
+	v, changed := f.DecMapIntfStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, canChange bool,
+	d *Decoder) (_ map[interface{}]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		v = make(map[interface{}]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uint)
+		v, changed := fastpathTV.DecMapIntfUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUintV(rv2i(rv).(map[interface{}]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, d *Decoder) {
+	v, changed := f.DecMapIntfUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, canChange bool,
+	d *Decoder) (_ map[interface{}]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uint8)
+		v, changed := fastpathTV.DecMapIntfUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUint8V(rv2i(rv).(map[interface{}]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, d *Decoder) {
+	v, changed := f.DecMapIntfUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, canChange bool,
+	d *Decoder) (_ map[interface{}]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[interface{}]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uint16)
+		v, changed := fastpathTV.DecMapIntfUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUint16V(rv2i(rv).(map[interface{}]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, d *Decoder) {
+	v, changed := f.DecMapIntfUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, canChange bool,
+	d *Decoder) (_ map[interface{}]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[interface{}]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uint32)
+		v, changed := fastpathTV.DecMapIntfUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUint32V(rv2i(rv).(map[interface{}]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, d *Decoder) {
+	v, changed := f.DecMapIntfUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, canChange bool,
+	d *Decoder) (_ map[interface{}]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[interface{}]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uint64)
+		v, changed := fastpathTV.DecMapIntfUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUint64V(rv2i(rv).(map[interface{}]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, d *Decoder) {
+	v, changed := f.DecMapIntfUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, canChange bool,
+	d *Decoder) (_ map[interface{}]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]uintptr)
+		v, changed := fastpathTV.DecMapIntfUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfUintptrV(rv2i(rv).(map[interface{}]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfUintptrX(vp *map[interface{}]uintptr, d *Decoder) {
+	v, changed := f.DecMapIntfUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfUintptrV(v map[interface{}]uintptr, canChange bool,
+	d *Decoder) (_ map[interface{}]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]int)
+		v, changed := fastpathTV.DecMapIntfIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfIntV(rv2i(rv).(map[interface{}]int), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, d *Decoder) {
+	v, changed := f.DecMapIntfIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, canChange bool,
+	d *Decoder) (_ map[interface{}]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]int8)
+		v, changed := fastpathTV.DecMapIntfInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfInt8V(rv2i(rv).(map[interface{}]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, d *Decoder) {
+	v, changed := f.DecMapIntfInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, canChange bool,
+	d *Decoder) (_ map[interface{}]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[interface{}]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]int16)
+		v, changed := fastpathTV.DecMapIntfInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfInt16V(rv2i(rv).(map[interface{}]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, d *Decoder) {
+	v, changed := f.DecMapIntfInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, canChange bool,
+	d *Decoder) (_ map[interface{}]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[interface{}]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]int32)
+		v, changed := fastpathTV.DecMapIntfInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfInt32V(rv2i(rv).(map[interface{}]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, d *Decoder) {
+	v, changed := f.DecMapIntfInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, canChange bool,
+	d *Decoder) (_ map[interface{}]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[interface{}]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]int64)
+		v, changed := fastpathTV.DecMapIntfInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfInt64V(rv2i(rv).(map[interface{}]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, d *Decoder) {
+	v, changed := f.DecMapIntfInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, canChange bool,
+	d *Decoder) (_ map[interface{}]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]float32)
+		v, changed := fastpathTV.DecMapIntfFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfFloat32V(rv2i(rv).(map[interface{}]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, d *Decoder) {
+	v, changed := f.DecMapIntfFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, canChange bool,
+	d *Decoder) (_ map[interface{}]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[interface{}]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]float64)
+		v, changed := fastpathTV.DecMapIntfFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfFloat64V(rv2i(rv).(map[interface{}]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, d *Decoder) {
+	v, changed := f.DecMapIntfFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, canChange bool,
+	d *Decoder) (_ map[interface{}]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[interface{}]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntfBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[interface{}]bool)
+		v, changed := fastpathTV.DecMapIntfBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntfBoolV(rv2i(rv).(map[interface{}]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, d *Decoder) {
+	v, changed := f.DecMapIntfBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, canChange bool,
+	d *Decoder) (_ map[interface{}]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[interface{}]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk interface{}
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = nil
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv)
+		}
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]interface{})
+		v, changed := fastpathTV.DecMapStringIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringIntfV(rv2i(rv).(map[string]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, d *Decoder) {
+	v, changed := f.DecMapStringIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, canChange bool,
+	d *Decoder) (_ map[string]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		v = make(map[string]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk string
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]string)
+		v, changed := fastpathTV.DecMapStringStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringStringV(rv2i(rv).(map[string]string), false, d)
+	}
+}
+func (f fastpathT) DecMapStringStringX(vp *map[string]string, d *Decoder) {
+	v, changed := f.DecMapStringStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringStringV(v map[string]string, canChange bool,
+	d *Decoder) (_ map[string]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 32)
+		v = make(map[string]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uint)
+		v, changed := fastpathTV.DecMapStringUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUintV(rv2i(rv).(map[string]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUintX(vp *map[string]uint, d *Decoder) {
+	v, changed := f.DecMapStringUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUintV(v map[string]uint, canChange bool,
+	d *Decoder) (_ map[string]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uint8)
+		v, changed := fastpathTV.DecMapStringUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUint8V(rv2i(rv).(map[string]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, d *Decoder) {
+	v, changed := f.DecMapStringUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, canChange bool,
+	d *Decoder) (_ map[string]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[string]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uint16)
+		v, changed := fastpathTV.DecMapStringUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUint16V(rv2i(rv).(map[string]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, d *Decoder) {
+	v, changed := f.DecMapStringUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, canChange bool,
+	d *Decoder) (_ map[string]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[string]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uint32)
+		v, changed := fastpathTV.DecMapStringUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUint32V(rv2i(rv).(map[string]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, d *Decoder) {
+	v, changed := f.DecMapStringUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, canChange bool,
+	d *Decoder) (_ map[string]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[string]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uint64)
+		v, changed := fastpathTV.DecMapStringUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUint64V(rv2i(rv).(map[string]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, d *Decoder) {
+	v, changed := f.DecMapStringUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, canChange bool,
+	d *Decoder) (_ map[string]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]uintptr)
+		v, changed := fastpathTV.DecMapStringUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringUintptrV(rv2i(rv).(map[string]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapStringUintptrX(vp *map[string]uintptr, d *Decoder) {
+	v, changed := f.DecMapStringUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringUintptrV(v map[string]uintptr, canChange bool,
+	d *Decoder) (_ map[string]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]int)
+		v, changed := fastpathTV.DecMapStringIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringIntV(rv2i(rv).(map[string]int), false, d)
+	}
+}
+func (f fastpathT) DecMapStringIntX(vp *map[string]int, d *Decoder) {
+	v, changed := f.DecMapStringIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringIntV(v map[string]int, canChange bool,
+	d *Decoder) (_ map[string]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]int8)
+		v, changed := fastpathTV.DecMapStringInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringInt8V(rv2i(rv).(map[string]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, d *Decoder) {
+	v, changed := f.DecMapStringInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringInt8V(v map[string]int8, canChange bool,
+	d *Decoder) (_ map[string]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[string]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]int16)
+		v, changed := fastpathTV.DecMapStringInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringInt16V(rv2i(rv).(map[string]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, d *Decoder) {
+	v, changed := f.DecMapStringInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringInt16V(v map[string]int16, canChange bool,
+	d *Decoder) (_ map[string]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[string]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]int32)
+		v, changed := fastpathTV.DecMapStringInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringInt32V(rv2i(rv).(map[string]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, d *Decoder) {
+	v, changed := f.DecMapStringInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringInt32V(v map[string]int32, canChange bool,
+	d *Decoder) (_ map[string]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[string]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]int64)
+		v, changed := fastpathTV.DecMapStringInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringInt64V(rv2i(rv).(map[string]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, d *Decoder) {
+	v, changed := f.DecMapStringInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringInt64V(v map[string]int64, canChange bool,
+	d *Decoder) (_ map[string]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]float32)
+		v, changed := fastpathTV.DecMapStringFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringFloat32V(rv2i(rv).(map[string]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, d *Decoder) {
+	v, changed := f.DecMapStringFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, canChange bool,
+	d *Decoder) (_ map[string]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[string]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]float64)
+		v, changed := fastpathTV.DecMapStringFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringFloat64V(rv2i(rv).(map[string]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, d *Decoder) {
+	v, changed := f.DecMapStringFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, canChange bool,
+	d *Decoder) (_ map[string]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[string]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapStringBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[string]bool)
+		v, changed := fastpathTV.DecMapStringBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapStringBoolV(rv2i(rv).(map[string]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, d *Decoder) {
+	v, changed := f.DecMapStringBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapStringBoolV(v map[string]bool, canChange bool,
+	d *Decoder) (_ map[string]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[string]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk string
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeString()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]interface{})
+		v, changed := fastpathTV.DecMapFloat32IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32IntfV(rv2i(rv).(map[float32]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, d *Decoder) {
+	v, changed := f.DecMapFloat32IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, canChange bool,
+	d *Decoder) (_ map[float32]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[float32]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk float32
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]string)
+		v, changed := fastpathTV.DecMapFloat32StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32StringV(rv2i(rv).(map[float32]string), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, d *Decoder) {
+	v, changed := f.DecMapFloat32StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, canChange bool,
+	d *Decoder) (_ map[float32]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[float32]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uint)
+		v, changed := fastpathTV.DecMapFloat32UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32UintV(rv2i(rv).(map[float32]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, d *Decoder) {
+	v, changed := f.DecMapFloat32UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, canChange bool,
+	d *Decoder) (_ map[float32]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uint8)
+		v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Uint8V(rv2i(rv).(map[float32]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, canChange bool,
+	d *Decoder) (_ map[float32]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[float32]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uint16)
+		v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Uint16V(rv2i(rv).(map[float32]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, canChange bool,
+	d *Decoder) (_ map[float32]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[float32]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uint32)
+		v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Uint32V(rv2i(rv).(map[float32]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, canChange bool,
+	d *Decoder) (_ map[float32]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[float32]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uint64)
+		v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Uint64V(rv2i(rv).(map[float32]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, d *Decoder) {
+	v, changed := f.DecMapFloat32Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, canChange bool,
+	d *Decoder) (_ map[float32]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]uintptr)
+		v, changed := fastpathTV.DecMapFloat32UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32UintptrV(rv2i(rv).(map[float32]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32UintptrX(vp *map[float32]uintptr, d *Decoder) {
+	v, changed := f.DecMapFloat32UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32UintptrV(v map[float32]uintptr, canChange bool,
+	d *Decoder) (_ map[float32]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]int)
+		v, changed := fastpathTV.DecMapFloat32IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32IntV(rv2i(rv).(map[float32]int), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, d *Decoder) {
+	v, changed := f.DecMapFloat32IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, canChange bool,
+	d *Decoder) (_ map[float32]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]int8)
+		v, changed := fastpathTV.DecMapFloat32Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Int8V(rv2i(rv).(map[float32]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, d *Decoder) {
+	v, changed := f.DecMapFloat32Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, canChange bool,
+	d *Decoder) (_ map[float32]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[float32]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]int16)
+		v, changed := fastpathTV.DecMapFloat32Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Int16V(rv2i(rv).(map[float32]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, d *Decoder) {
+	v, changed := f.DecMapFloat32Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, canChange bool,
+	d *Decoder) (_ map[float32]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[float32]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]int32)
+		v, changed := fastpathTV.DecMapFloat32Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Int32V(rv2i(rv).(map[float32]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, d *Decoder) {
+	v, changed := f.DecMapFloat32Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, canChange bool,
+	d *Decoder) (_ map[float32]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[float32]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]int64)
+		v, changed := fastpathTV.DecMapFloat32Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Int64V(rv2i(rv).(map[float32]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, d *Decoder) {
+	v, changed := f.DecMapFloat32Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, canChange bool,
+	d *Decoder) (_ map[float32]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]float32)
+		v, changed := fastpathTV.DecMapFloat32Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Float32V(rv2i(rv).(map[float32]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, d *Decoder) {
+	v, changed := f.DecMapFloat32Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, canChange bool,
+	d *Decoder) (_ map[float32]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[float32]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]float64)
+		v, changed := fastpathTV.DecMapFloat32Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32Float64V(rv2i(rv).(map[float32]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, d *Decoder) {
+	v, changed := f.DecMapFloat32Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, canChange bool,
+	d *Decoder) (_ map[float32]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float32]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat32BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float32]bool)
+		v, changed := fastpathTV.DecMapFloat32BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat32BoolV(rv2i(rv).(map[float32]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, d *Decoder) {
+	v, changed := f.DecMapFloat32BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, canChange bool,
+	d *Decoder) (_ map[float32]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[float32]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float32
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]interface{})
+		v, changed := fastpathTV.DecMapFloat64IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64IntfV(rv2i(rv).(map[float64]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, d *Decoder) {
+	v, changed := f.DecMapFloat64IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, canChange bool,
+	d *Decoder) (_ map[float64]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[float64]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk float64
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]string)
+		v, changed := fastpathTV.DecMapFloat64StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64StringV(rv2i(rv).(map[float64]string), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, d *Decoder) {
+	v, changed := f.DecMapFloat64StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, canChange bool,
+	d *Decoder) (_ map[float64]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[float64]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uint)
+		v, changed := fastpathTV.DecMapFloat64UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64UintV(rv2i(rv).(map[float64]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, d *Decoder) {
+	v, changed := f.DecMapFloat64UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, canChange bool,
+	d *Decoder) (_ map[float64]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uint8)
+		v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Uint8V(rv2i(rv).(map[float64]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, canChange bool,
+	d *Decoder) (_ map[float64]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[float64]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uint16)
+		v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Uint16V(rv2i(rv).(map[float64]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, canChange bool,
+	d *Decoder) (_ map[float64]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[float64]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uint32)
+		v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Uint32V(rv2i(rv).(map[float64]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, canChange bool,
+	d *Decoder) (_ map[float64]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float64]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uint64)
+		v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Uint64V(rv2i(rv).(map[float64]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, d *Decoder) {
+	v, changed := f.DecMapFloat64Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, canChange bool,
+	d *Decoder) (_ map[float64]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]uintptr)
+		v, changed := fastpathTV.DecMapFloat64UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64UintptrV(rv2i(rv).(map[float64]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64UintptrX(vp *map[float64]uintptr, d *Decoder) {
+	v, changed := f.DecMapFloat64UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64UintptrV(v map[float64]uintptr, canChange bool,
+	d *Decoder) (_ map[float64]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]int)
+		v, changed := fastpathTV.DecMapFloat64IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64IntV(rv2i(rv).(map[float64]int), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, d *Decoder) {
+	v, changed := f.DecMapFloat64IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, canChange bool,
+	d *Decoder) (_ map[float64]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]int8)
+		v, changed := fastpathTV.DecMapFloat64Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Int8V(rv2i(rv).(map[float64]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, d *Decoder) {
+	v, changed := f.DecMapFloat64Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, canChange bool,
+	d *Decoder) (_ map[float64]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[float64]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]int16)
+		v, changed := fastpathTV.DecMapFloat64Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Int16V(rv2i(rv).(map[float64]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, d *Decoder) {
+	v, changed := f.DecMapFloat64Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, canChange bool,
+	d *Decoder) (_ map[float64]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[float64]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]int32)
+		v, changed := fastpathTV.DecMapFloat64Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Int32V(rv2i(rv).(map[float64]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, d *Decoder) {
+	v, changed := f.DecMapFloat64Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, canChange bool,
+	d *Decoder) (_ map[float64]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float64]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]int64)
+		v, changed := fastpathTV.DecMapFloat64Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Int64V(rv2i(rv).(map[float64]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, d *Decoder) {
+	v, changed := f.DecMapFloat64Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, canChange bool,
+	d *Decoder) (_ map[float64]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]float32)
+		v, changed := fastpathTV.DecMapFloat64Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Float32V(rv2i(rv).(map[float64]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, d *Decoder) {
+	v, changed := f.DecMapFloat64Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, canChange bool,
+	d *Decoder) (_ map[float64]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[float64]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]float64)
+		v, changed := fastpathTV.DecMapFloat64Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64Float64V(rv2i(rv).(map[float64]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, d *Decoder) {
+	v, changed := f.DecMapFloat64Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, canChange bool,
+	d *Decoder) (_ map[float64]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[float64]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapFloat64BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[float64]bool)
+		v, changed := fastpathTV.DecMapFloat64BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapFloat64BoolV(rv2i(rv).(map[float64]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, d *Decoder) {
+	v, changed := f.DecMapFloat64BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, canChange bool,
+	d *Decoder) (_ map[float64]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[float64]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk float64
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeFloat64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]interface{})
+		v, changed := fastpathTV.DecMapUintIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintIntfV(rv2i(rv).(map[uint]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, d *Decoder) {
+	v, changed := f.DecMapUintIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, canChange bool,
+	d *Decoder) (_ map[uint]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uint]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uint
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]string)
+		v, changed := fastpathTV.DecMapUintStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintStringV(rv2i(rv).(map[uint]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUintStringX(vp *map[uint]string, d *Decoder) {
+	v, changed := f.DecMapUintStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintStringV(v map[uint]string, canChange bool,
+	d *Decoder) (_ map[uint]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uint]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uint)
+		v, changed := fastpathTV.DecMapUintUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUintV(rv2i(rv).(map[uint]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, d *Decoder) {
+	v, changed := f.DecMapUintUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUintV(v map[uint]uint, canChange bool,
+	d *Decoder) (_ map[uint]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uint8)
+		v, changed := fastpathTV.DecMapUintUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUint8V(rv2i(rv).(map[uint]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, d *Decoder) {
+	v, changed := f.DecMapUintUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, canChange bool,
+	d *Decoder) (_ map[uint]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uint16)
+		v, changed := fastpathTV.DecMapUintUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUint16V(rv2i(rv).(map[uint]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, d *Decoder) {
+	v, changed := f.DecMapUintUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, canChange bool,
+	d *Decoder) (_ map[uint]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uint32)
+		v, changed := fastpathTV.DecMapUintUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUint32V(rv2i(rv).(map[uint]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, d *Decoder) {
+	v, changed := f.DecMapUintUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, canChange bool,
+	d *Decoder) (_ map[uint]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uint64)
+		v, changed := fastpathTV.DecMapUintUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUint64V(rv2i(rv).(map[uint]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, d *Decoder) {
+	v, changed := f.DecMapUintUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, canChange bool,
+	d *Decoder) (_ map[uint]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]uintptr)
+		v, changed := fastpathTV.DecMapUintUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintUintptrV(rv2i(rv).(map[uint]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUintUintptrX(vp *map[uint]uintptr, d *Decoder) {
+	v, changed := f.DecMapUintUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintUintptrV(v map[uint]uintptr, canChange bool,
+	d *Decoder) (_ map[uint]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]int)
+		v, changed := fastpathTV.DecMapUintIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintIntV(rv2i(rv).(map[uint]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUintIntX(vp *map[uint]int, d *Decoder) {
+	v, changed := f.DecMapUintIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintIntV(v map[uint]int, canChange bool,
+	d *Decoder) (_ map[uint]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]int8)
+		v, changed := fastpathTV.DecMapUintInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintInt8V(rv2i(rv).(map[uint]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, d *Decoder) {
+	v, changed := f.DecMapUintInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, canChange bool,
+	d *Decoder) (_ map[uint]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]int16)
+		v, changed := fastpathTV.DecMapUintInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintInt16V(rv2i(rv).(map[uint]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, d *Decoder) {
+	v, changed := f.DecMapUintInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, canChange bool,
+	d *Decoder) (_ map[uint]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]int32)
+		v, changed := fastpathTV.DecMapUintInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintInt32V(rv2i(rv).(map[uint]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, d *Decoder) {
+	v, changed := f.DecMapUintInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, canChange bool,
+	d *Decoder) (_ map[uint]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]int64)
+		v, changed := fastpathTV.DecMapUintInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintInt64V(rv2i(rv).(map[uint]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, d *Decoder) {
+	v, changed := f.DecMapUintInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, canChange bool,
+	d *Decoder) (_ map[uint]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]float32)
+		v, changed := fastpathTV.DecMapUintFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintFloat32V(rv2i(rv).(map[uint]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, d *Decoder) {
+	v, changed := f.DecMapUintFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, canChange bool,
+	d *Decoder) (_ map[uint]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]float64)
+		v, changed := fastpathTV.DecMapUintFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintFloat64V(rv2i(rv).(map[uint]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, d *Decoder) {
+	v, changed := f.DecMapUintFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, canChange bool,
+	d *Decoder) (_ map[uint]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint]bool)
+		v, changed := fastpathTV.DecMapUintBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintBoolV(rv2i(rv).(map[uint]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, d *Decoder) {
+	v, changed := f.DecMapUintBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, canChange bool,
+	d *Decoder) (_ map[uint]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]interface{})
+		v, changed := fastpathTV.DecMapUint8IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8IntfV(rv2i(rv).(map[uint8]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, d *Decoder) {
+	v, changed := f.DecMapUint8IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, canChange bool,
+	d *Decoder) (_ map[uint8]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[uint8]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uint8
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]string)
+		v, changed := fastpathTV.DecMapUint8StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8StringV(rv2i(rv).(map[uint8]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, d *Decoder) {
+	v, changed := f.DecMapUint8StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, canChange bool,
+	d *Decoder) (_ map[uint8]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[uint8]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uint)
+		v, changed := fastpathTV.DecMapUint8UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8UintV(rv2i(rv).(map[uint8]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, d *Decoder) {
+	v, changed := f.DecMapUint8UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, canChange bool,
+	d *Decoder) (_ map[uint8]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uint8)
+		v, changed := fastpathTV.DecMapUint8Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Uint8V(rv2i(rv).(map[uint8]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, d *Decoder) {
+	v, changed := f.DecMapUint8Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, canChange bool,
+	d *Decoder) (_ map[uint8]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[uint8]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uint16)
+		v, changed := fastpathTV.DecMapUint8Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Uint16V(rv2i(rv).(map[uint8]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, d *Decoder) {
+	v, changed := f.DecMapUint8Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, canChange bool,
+	d *Decoder) (_ map[uint8]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[uint8]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uint32)
+		v, changed := fastpathTV.DecMapUint8Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Uint32V(rv2i(rv).(map[uint8]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, d *Decoder) {
+	v, changed := f.DecMapUint8Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, canChange bool,
+	d *Decoder) (_ map[uint8]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint8]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uint64)
+		v, changed := fastpathTV.DecMapUint8Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Uint64V(rv2i(rv).(map[uint8]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, d *Decoder) {
+	v, changed := f.DecMapUint8Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, canChange bool,
+	d *Decoder) (_ map[uint8]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]uintptr)
+		v, changed := fastpathTV.DecMapUint8UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8UintptrV(rv2i(rv).(map[uint8]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8UintptrX(vp *map[uint8]uintptr, d *Decoder) {
+	v, changed := f.DecMapUint8UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8UintptrV(v map[uint8]uintptr, canChange bool,
+	d *Decoder) (_ map[uint8]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]int)
+		v, changed := fastpathTV.DecMapUint8IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8IntV(rv2i(rv).(map[uint8]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, d *Decoder) {
+	v, changed := f.DecMapUint8IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, canChange bool,
+	d *Decoder) (_ map[uint8]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]int8)
+		v, changed := fastpathTV.DecMapUint8Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Int8V(rv2i(rv).(map[uint8]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, d *Decoder) {
+	v, changed := f.DecMapUint8Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, canChange bool,
+	d *Decoder) (_ map[uint8]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[uint8]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]int16)
+		v, changed := fastpathTV.DecMapUint8Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Int16V(rv2i(rv).(map[uint8]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, d *Decoder) {
+	v, changed := f.DecMapUint8Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, canChange bool,
+	d *Decoder) (_ map[uint8]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[uint8]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]int32)
+		v, changed := fastpathTV.DecMapUint8Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Int32V(rv2i(rv).(map[uint8]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, d *Decoder) {
+	v, changed := f.DecMapUint8Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, canChange bool,
+	d *Decoder) (_ map[uint8]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint8]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]int64)
+		v, changed := fastpathTV.DecMapUint8Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Int64V(rv2i(rv).(map[uint8]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, d *Decoder) {
+	v, changed := f.DecMapUint8Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, canChange bool,
+	d *Decoder) (_ map[uint8]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]float32)
+		v, changed := fastpathTV.DecMapUint8Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Float32V(rv2i(rv).(map[uint8]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, d *Decoder) {
+	v, changed := f.DecMapUint8Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, canChange bool,
+	d *Decoder) (_ map[uint8]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint8]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]float64)
+		v, changed := fastpathTV.DecMapUint8Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8Float64V(rv2i(rv).(map[uint8]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, d *Decoder) {
+	v, changed := f.DecMapUint8Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, canChange bool,
+	d *Decoder) (_ map[uint8]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint8]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint8BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint8]bool)
+		v, changed := fastpathTV.DecMapUint8BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint8BoolV(rv2i(rv).(map[uint8]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, d *Decoder) {
+	v, changed := f.DecMapUint8BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, canChange bool,
+	d *Decoder) (_ map[uint8]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[uint8]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint8
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]interface{})
+		v, changed := fastpathTV.DecMapUint16IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16IntfV(rv2i(rv).(map[uint16]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, d *Decoder) {
+	v, changed := f.DecMapUint16IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, canChange bool,
+	d *Decoder) (_ map[uint16]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[uint16]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uint16
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]string)
+		v, changed := fastpathTV.DecMapUint16StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16StringV(rv2i(rv).(map[uint16]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, d *Decoder) {
+	v, changed := f.DecMapUint16StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, canChange bool,
+	d *Decoder) (_ map[uint16]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[uint16]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uint)
+		v, changed := fastpathTV.DecMapUint16UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16UintV(rv2i(rv).(map[uint16]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, d *Decoder) {
+	v, changed := f.DecMapUint16UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, canChange bool,
+	d *Decoder) (_ map[uint16]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uint8)
+		v, changed := fastpathTV.DecMapUint16Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Uint8V(rv2i(rv).(map[uint16]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, d *Decoder) {
+	v, changed := f.DecMapUint16Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, canChange bool,
+	d *Decoder) (_ map[uint16]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[uint16]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uint16)
+		v, changed := fastpathTV.DecMapUint16Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Uint16V(rv2i(rv).(map[uint16]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, d *Decoder) {
+	v, changed := f.DecMapUint16Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, canChange bool,
+	d *Decoder) (_ map[uint16]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		v = make(map[uint16]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uint32)
+		v, changed := fastpathTV.DecMapUint16Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Uint32V(rv2i(rv).(map[uint16]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, d *Decoder) {
+	v, changed := f.DecMapUint16Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, canChange bool,
+	d *Decoder) (_ map[uint16]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[uint16]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uint64)
+		v, changed := fastpathTV.DecMapUint16Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Uint64V(rv2i(rv).(map[uint16]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, d *Decoder) {
+	v, changed := f.DecMapUint16Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, canChange bool,
+	d *Decoder) (_ map[uint16]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]uintptr)
+		v, changed := fastpathTV.DecMapUint16UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16UintptrV(rv2i(rv).(map[uint16]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16UintptrX(vp *map[uint16]uintptr, d *Decoder) {
+	v, changed := f.DecMapUint16UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16UintptrV(v map[uint16]uintptr, canChange bool,
+	d *Decoder) (_ map[uint16]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]int)
+		v, changed := fastpathTV.DecMapUint16IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16IntV(rv2i(rv).(map[uint16]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, d *Decoder) {
+	v, changed := f.DecMapUint16IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, canChange bool,
+	d *Decoder) (_ map[uint16]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]int8)
+		v, changed := fastpathTV.DecMapUint16Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Int8V(rv2i(rv).(map[uint16]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, d *Decoder) {
+	v, changed := f.DecMapUint16Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, canChange bool,
+	d *Decoder) (_ map[uint16]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[uint16]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]int16)
+		v, changed := fastpathTV.DecMapUint16Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Int16V(rv2i(rv).(map[uint16]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, d *Decoder) {
+	v, changed := f.DecMapUint16Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, canChange bool,
+	d *Decoder) (_ map[uint16]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		v = make(map[uint16]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]int32)
+		v, changed := fastpathTV.DecMapUint16Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Int32V(rv2i(rv).(map[uint16]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, d *Decoder) {
+	v, changed := f.DecMapUint16Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, canChange bool,
+	d *Decoder) (_ map[uint16]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[uint16]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]int64)
+		v, changed := fastpathTV.DecMapUint16Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Int64V(rv2i(rv).(map[uint16]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, d *Decoder) {
+	v, changed := f.DecMapUint16Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, canChange bool,
+	d *Decoder) (_ map[uint16]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]float32)
+		v, changed := fastpathTV.DecMapUint16Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Float32V(rv2i(rv).(map[uint16]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, d *Decoder) {
+	v, changed := f.DecMapUint16Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, canChange bool,
+	d *Decoder) (_ map[uint16]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[uint16]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]float64)
+		v, changed := fastpathTV.DecMapUint16Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16Float64V(rv2i(rv).(map[uint16]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, d *Decoder) {
+	v, changed := f.DecMapUint16Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, canChange bool,
+	d *Decoder) (_ map[uint16]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint16]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint16BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint16]bool)
+		v, changed := fastpathTV.DecMapUint16BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint16BoolV(rv2i(rv).(map[uint16]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, d *Decoder) {
+	v, changed := f.DecMapUint16BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, canChange bool,
+	d *Decoder) (_ map[uint16]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[uint16]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint16
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]interface{})
+		v, changed := fastpathTV.DecMapUint32IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32IntfV(rv2i(rv).(map[uint32]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, d *Decoder) {
+	v, changed := f.DecMapUint32IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, canChange bool,
+	d *Decoder) (_ map[uint32]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[uint32]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uint32
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]string)
+		v, changed := fastpathTV.DecMapUint32StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32StringV(rv2i(rv).(map[uint32]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, d *Decoder) {
+	v, changed := f.DecMapUint32StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, canChange bool,
+	d *Decoder) (_ map[uint32]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[uint32]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uint)
+		v, changed := fastpathTV.DecMapUint32UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32UintV(rv2i(rv).(map[uint32]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, d *Decoder) {
+	v, changed := f.DecMapUint32UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, canChange bool,
+	d *Decoder) (_ map[uint32]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uint8)
+		v, changed := fastpathTV.DecMapUint32Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Uint8V(rv2i(rv).(map[uint32]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, d *Decoder) {
+	v, changed := f.DecMapUint32Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, canChange bool,
+	d *Decoder) (_ map[uint32]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint32]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uint16)
+		v, changed := fastpathTV.DecMapUint32Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Uint16V(rv2i(rv).(map[uint32]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, d *Decoder) {
+	v, changed := f.DecMapUint32Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, canChange bool,
+	d *Decoder) (_ map[uint32]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[uint32]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uint32)
+		v, changed := fastpathTV.DecMapUint32Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Uint32V(rv2i(rv).(map[uint32]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, d *Decoder) {
+	v, changed := f.DecMapUint32Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, canChange bool,
+	d *Decoder) (_ map[uint32]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[uint32]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uint64)
+		v, changed := fastpathTV.DecMapUint32Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Uint64V(rv2i(rv).(map[uint32]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, d *Decoder) {
+	v, changed := f.DecMapUint32Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, canChange bool,
+	d *Decoder) (_ map[uint32]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]uintptr)
+		v, changed := fastpathTV.DecMapUint32UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32UintptrV(rv2i(rv).(map[uint32]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32UintptrX(vp *map[uint32]uintptr, d *Decoder) {
+	v, changed := f.DecMapUint32UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32UintptrV(v map[uint32]uintptr, canChange bool,
+	d *Decoder) (_ map[uint32]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]int)
+		v, changed := fastpathTV.DecMapUint32IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32IntV(rv2i(rv).(map[uint32]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, d *Decoder) {
+	v, changed := f.DecMapUint32IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, canChange bool,
+	d *Decoder) (_ map[uint32]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]int8)
+		v, changed := fastpathTV.DecMapUint32Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Int8V(rv2i(rv).(map[uint32]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, d *Decoder) {
+	v, changed := f.DecMapUint32Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, canChange bool,
+	d *Decoder) (_ map[uint32]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint32]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]int16)
+		v, changed := fastpathTV.DecMapUint32Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Int16V(rv2i(rv).(map[uint32]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, d *Decoder) {
+	v, changed := f.DecMapUint32Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, canChange bool,
+	d *Decoder) (_ map[uint32]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[uint32]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]int32)
+		v, changed := fastpathTV.DecMapUint32Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Int32V(rv2i(rv).(map[uint32]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, d *Decoder) {
+	v, changed := f.DecMapUint32Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, canChange bool,
+	d *Decoder) (_ map[uint32]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[uint32]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]int64)
+		v, changed := fastpathTV.DecMapUint32Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Int64V(rv2i(rv).(map[uint32]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, d *Decoder) {
+	v, changed := f.DecMapUint32Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, canChange bool,
+	d *Decoder) (_ map[uint32]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]float32)
+		v, changed := fastpathTV.DecMapUint32Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Float32V(rv2i(rv).(map[uint32]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, d *Decoder) {
+	v, changed := f.DecMapUint32Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, canChange bool,
+	d *Decoder) (_ map[uint32]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[uint32]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]float64)
+		v, changed := fastpathTV.DecMapUint32Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32Float64V(rv2i(rv).(map[uint32]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, d *Decoder) {
+	v, changed := f.DecMapUint32Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, canChange bool,
+	d *Decoder) (_ map[uint32]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint32]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint32BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint32]bool)
+		v, changed := fastpathTV.DecMapUint32BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint32BoolV(rv2i(rv).(map[uint32]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, d *Decoder) {
+	v, changed := f.DecMapUint32BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, canChange bool,
+	d *Decoder) (_ map[uint32]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[uint32]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint32
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]interface{})
+		v, changed := fastpathTV.DecMapUint64IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64IntfV(rv2i(rv).(map[uint64]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, d *Decoder) {
+	v, changed := f.DecMapUint64IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, canChange bool,
+	d *Decoder) (_ map[uint64]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uint64]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uint64
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]string)
+		v, changed := fastpathTV.DecMapUint64StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64StringV(rv2i(rv).(map[uint64]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, d *Decoder) {
+	v, changed := f.DecMapUint64StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, canChange bool,
+	d *Decoder) (_ map[uint64]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uint64]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uint)
+		v, changed := fastpathTV.DecMapUint64UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64UintV(rv2i(rv).(map[uint64]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, d *Decoder) {
+	v, changed := f.DecMapUint64UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, canChange bool,
+	d *Decoder) (_ map[uint64]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uint8)
+		v, changed := fastpathTV.DecMapUint64Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Uint8V(rv2i(rv).(map[uint64]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, d *Decoder) {
+	v, changed := f.DecMapUint64Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, canChange bool,
+	d *Decoder) (_ map[uint64]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint64]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uint16)
+		v, changed := fastpathTV.DecMapUint64Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Uint16V(rv2i(rv).(map[uint64]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, d *Decoder) {
+	v, changed := f.DecMapUint64Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, canChange bool,
+	d *Decoder) (_ map[uint64]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint64]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uint32)
+		v, changed := fastpathTV.DecMapUint64Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Uint32V(rv2i(rv).(map[uint64]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, d *Decoder) {
+	v, changed := f.DecMapUint64Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, canChange bool,
+	d *Decoder) (_ map[uint64]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint64]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uint64)
+		v, changed := fastpathTV.DecMapUint64Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Uint64V(rv2i(rv).(map[uint64]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, d *Decoder) {
+	v, changed := f.DecMapUint64Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, canChange bool,
+	d *Decoder) (_ map[uint64]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]uintptr)
+		v, changed := fastpathTV.DecMapUint64UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64UintptrV(rv2i(rv).(map[uint64]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64UintptrX(vp *map[uint64]uintptr, d *Decoder) {
+	v, changed := f.DecMapUint64UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64UintptrV(v map[uint64]uintptr, canChange bool,
+	d *Decoder) (_ map[uint64]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]int)
+		v, changed := fastpathTV.DecMapUint64IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64IntV(rv2i(rv).(map[uint64]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, d *Decoder) {
+	v, changed := f.DecMapUint64IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, canChange bool,
+	d *Decoder) (_ map[uint64]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]int8)
+		v, changed := fastpathTV.DecMapUint64Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Int8V(rv2i(rv).(map[uint64]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, d *Decoder) {
+	v, changed := f.DecMapUint64Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, canChange bool,
+	d *Decoder) (_ map[uint64]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint64]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]int16)
+		v, changed := fastpathTV.DecMapUint64Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Int16V(rv2i(rv).(map[uint64]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, d *Decoder) {
+	v, changed := f.DecMapUint64Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, canChange bool,
+	d *Decoder) (_ map[uint64]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uint64]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]int32)
+		v, changed := fastpathTV.DecMapUint64Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Int32V(rv2i(rv).(map[uint64]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, d *Decoder) {
+	v, changed := f.DecMapUint64Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, canChange bool,
+	d *Decoder) (_ map[uint64]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint64]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]int64)
+		v, changed := fastpathTV.DecMapUint64Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Int64V(rv2i(rv).(map[uint64]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, d *Decoder) {
+	v, changed := f.DecMapUint64Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, canChange bool,
+	d *Decoder) (_ map[uint64]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]float32)
+		v, changed := fastpathTV.DecMapUint64Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Float32V(rv2i(rv).(map[uint64]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, d *Decoder) {
+	v, changed := f.DecMapUint64Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, canChange bool,
+	d *Decoder) (_ map[uint64]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uint64]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]float64)
+		v, changed := fastpathTV.DecMapUint64Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64Float64V(rv2i(rv).(map[uint64]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, d *Decoder) {
+	v, changed := f.DecMapUint64Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, canChange bool,
+	d *Decoder) (_ map[uint64]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uint64]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUint64BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uint64]bool)
+		v, changed := fastpathTV.DecMapUint64BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUint64BoolV(rv2i(rv).(map[uint64]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, d *Decoder) {
+	v, changed := f.DecMapUint64BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, canChange bool,
+	d *Decoder) (_ map[uint64]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uint64]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uint64
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeUint64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]interface{})
+		v, changed := fastpathTV.DecMapUintptrIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrIntfV(rv2i(rv).(map[uintptr]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrIntfX(vp *map[uintptr]interface{}, d *Decoder) {
+	v, changed := f.DecMapUintptrIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrIntfV(v map[uintptr]interface{}, canChange bool,
+	d *Decoder) (_ map[uintptr]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uintptr]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk uintptr
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]string)
+		v, changed := fastpathTV.DecMapUintptrStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrStringV(rv2i(rv).(map[uintptr]string), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrStringX(vp *map[uintptr]string, d *Decoder) {
+	v, changed := f.DecMapUintptrStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrStringV(v map[uintptr]string, canChange bool,
+	d *Decoder) (_ map[uintptr]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[uintptr]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uint)
+		v, changed := fastpathTV.DecMapUintptrUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUintV(rv2i(rv).(map[uintptr]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUintX(vp *map[uintptr]uint, d *Decoder) {
+	v, changed := f.DecMapUintptrUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUintV(v map[uintptr]uint, canChange bool,
+	d *Decoder) (_ map[uintptr]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uint8)
+		v, changed := fastpathTV.DecMapUintptrUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUint8V(rv2i(rv).(map[uintptr]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUint8X(vp *map[uintptr]uint8, d *Decoder) {
+	v, changed := f.DecMapUintptrUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUint8V(v map[uintptr]uint8, canChange bool,
+	d *Decoder) (_ map[uintptr]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uintptr]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uint16)
+		v, changed := fastpathTV.DecMapUintptrUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUint16V(rv2i(rv).(map[uintptr]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUint16X(vp *map[uintptr]uint16, d *Decoder) {
+	v, changed := f.DecMapUintptrUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUint16V(v map[uintptr]uint16, canChange bool,
+	d *Decoder) (_ map[uintptr]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uintptr]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uint32)
+		v, changed := fastpathTV.DecMapUintptrUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUint32V(rv2i(rv).(map[uintptr]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUint32X(vp *map[uintptr]uint32, d *Decoder) {
+	v, changed := f.DecMapUintptrUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUint32V(v map[uintptr]uint32, canChange bool,
+	d *Decoder) (_ map[uintptr]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uintptr]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uint64)
+		v, changed := fastpathTV.DecMapUintptrUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUint64V(rv2i(rv).(map[uintptr]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUint64X(vp *map[uintptr]uint64, d *Decoder) {
+	v, changed := f.DecMapUintptrUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUint64V(v map[uintptr]uint64, canChange bool,
+	d *Decoder) (_ map[uintptr]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]uintptr)
+		v, changed := fastpathTV.DecMapUintptrUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrUintptrV(rv2i(rv).(map[uintptr]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrUintptrX(vp *map[uintptr]uintptr, d *Decoder) {
+	v, changed := f.DecMapUintptrUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrUintptrV(v map[uintptr]uintptr, canChange bool,
+	d *Decoder) (_ map[uintptr]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]int)
+		v, changed := fastpathTV.DecMapUintptrIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrIntV(rv2i(rv).(map[uintptr]int), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrIntX(vp *map[uintptr]int, d *Decoder) {
+	v, changed := f.DecMapUintptrIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrIntV(v map[uintptr]int, canChange bool,
+	d *Decoder) (_ map[uintptr]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]int8)
+		v, changed := fastpathTV.DecMapUintptrInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrInt8V(rv2i(rv).(map[uintptr]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrInt8X(vp *map[uintptr]int8, d *Decoder) {
+	v, changed := f.DecMapUintptrInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrInt8V(v map[uintptr]int8, canChange bool,
+	d *Decoder) (_ map[uintptr]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uintptr]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]int16)
+		v, changed := fastpathTV.DecMapUintptrInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrInt16V(rv2i(rv).(map[uintptr]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrInt16X(vp *map[uintptr]int16, d *Decoder) {
+	v, changed := f.DecMapUintptrInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrInt16V(v map[uintptr]int16, canChange bool,
+	d *Decoder) (_ map[uintptr]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[uintptr]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]int32)
+		v, changed := fastpathTV.DecMapUintptrInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrInt32V(rv2i(rv).(map[uintptr]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrInt32X(vp *map[uintptr]int32, d *Decoder) {
+	v, changed := f.DecMapUintptrInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrInt32V(v map[uintptr]int32, canChange bool,
+	d *Decoder) (_ map[uintptr]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uintptr]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]int64)
+		v, changed := fastpathTV.DecMapUintptrInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrInt64V(rv2i(rv).(map[uintptr]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrInt64X(vp *map[uintptr]int64, d *Decoder) {
+	v, changed := f.DecMapUintptrInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrInt64V(v map[uintptr]int64, canChange bool,
+	d *Decoder) (_ map[uintptr]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]float32)
+		v, changed := fastpathTV.DecMapUintptrFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrFloat32V(rv2i(rv).(map[uintptr]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrFloat32X(vp *map[uintptr]float32, d *Decoder) {
+	v, changed := f.DecMapUintptrFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrFloat32V(v map[uintptr]float32, canChange bool,
+	d *Decoder) (_ map[uintptr]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[uintptr]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]float64)
+		v, changed := fastpathTV.DecMapUintptrFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrFloat64V(rv2i(rv).(map[uintptr]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrFloat64X(vp *map[uintptr]float64, d *Decoder) {
+	v, changed := f.DecMapUintptrFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrFloat64V(v map[uintptr]float64, canChange bool,
+	d *Decoder) (_ map[uintptr]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[uintptr]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapUintptrBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[uintptr]bool)
+		v, changed := fastpathTV.DecMapUintptrBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapUintptrBoolV(rv2i(rv).(map[uintptr]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapUintptrBoolX(vp *map[uintptr]bool, d *Decoder) {
+	v, changed := f.DecMapUintptrBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapUintptrBoolV(v map[uintptr]bool, canChange bool,
+	d *Decoder) (_ map[uintptr]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[uintptr]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk uintptr
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]interface{})
+		v, changed := fastpathTV.DecMapIntIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntIntfV(rv2i(rv).(map[int]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, d *Decoder) {
+	v, changed := f.DecMapIntIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, canChange bool,
+	d *Decoder) (_ map[int]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[int]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk int
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]string)
+		v, changed := fastpathTV.DecMapIntStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntStringV(rv2i(rv).(map[int]string), false, d)
+	}
+}
+func (f fastpathT) DecMapIntStringX(vp *map[int]string, d *Decoder) {
+	v, changed := f.DecMapIntStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntStringV(v map[int]string, canChange bool,
+	d *Decoder) (_ map[int]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[int]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uint)
+		v, changed := fastpathTV.DecMapIntUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUintV(rv2i(rv).(map[int]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUintX(vp *map[int]uint, d *Decoder) {
+	v, changed := f.DecMapIntUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUintV(v map[int]uint, canChange bool,
+	d *Decoder) (_ map[int]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uint8)
+		v, changed := fastpathTV.DecMapIntUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUint8V(rv2i(rv).(map[int]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, d *Decoder) {
+	v, changed := f.DecMapIntUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, canChange bool,
+	d *Decoder) (_ map[int]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uint16)
+		v, changed := fastpathTV.DecMapIntUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUint16V(rv2i(rv).(map[int]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, d *Decoder) {
+	v, changed := f.DecMapIntUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, canChange bool,
+	d *Decoder) (_ map[int]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uint32)
+		v, changed := fastpathTV.DecMapIntUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUint32V(rv2i(rv).(map[int]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, d *Decoder) {
+	v, changed := f.DecMapIntUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, canChange bool,
+	d *Decoder) (_ map[int]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uint64)
+		v, changed := fastpathTV.DecMapIntUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUint64V(rv2i(rv).(map[int]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, d *Decoder) {
+	v, changed := f.DecMapIntUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, canChange bool,
+	d *Decoder) (_ map[int]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]uintptr)
+		v, changed := fastpathTV.DecMapIntUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntUintptrV(rv2i(rv).(map[int]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapIntUintptrX(vp *map[int]uintptr, d *Decoder) {
+	v, changed := f.DecMapIntUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntUintptrV(v map[int]uintptr, canChange bool,
+	d *Decoder) (_ map[int]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]int)
+		v, changed := fastpathTV.DecMapIntIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntIntV(rv2i(rv).(map[int]int), false, d)
+	}
+}
+func (f fastpathT) DecMapIntIntX(vp *map[int]int, d *Decoder) {
+	v, changed := f.DecMapIntIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntIntV(v map[int]int, canChange bool,
+	d *Decoder) (_ map[int]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]int8)
+		v, changed := fastpathTV.DecMapIntInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntInt8V(rv2i(rv).(map[int]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, d *Decoder) {
+	v, changed := f.DecMapIntInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntInt8V(v map[int]int8, canChange bool,
+	d *Decoder) (_ map[int]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]int16)
+		v, changed := fastpathTV.DecMapIntInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntInt16V(rv2i(rv).(map[int]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, d *Decoder) {
+	v, changed := f.DecMapIntInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntInt16V(v map[int]int16, canChange bool,
+	d *Decoder) (_ map[int]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]int32)
+		v, changed := fastpathTV.DecMapIntInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntInt32V(rv2i(rv).(map[int]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, d *Decoder) {
+	v, changed := f.DecMapIntInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntInt32V(v map[int]int32, canChange bool,
+	d *Decoder) (_ map[int]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]int64)
+		v, changed := fastpathTV.DecMapIntInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntInt64V(rv2i(rv).(map[int]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, d *Decoder) {
+	v, changed := f.DecMapIntInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntInt64V(v map[int]int64, canChange bool,
+	d *Decoder) (_ map[int]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]float32)
+		v, changed := fastpathTV.DecMapIntFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntFloat32V(rv2i(rv).(map[int]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, d *Decoder) {
+	v, changed := f.DecMapIntFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, canChange bool,
+	d *Decoder) (_ map[int]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]float64)
+		v, changed := fastpathTV.DecMapIntFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntFloat64V(rv2i(rv).(map[int]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, d *Decoder) {
+	v, changed := f.DecMapIntFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, canChange bool,
+	d *Decoder) (_ map[int]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapIntBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int]bool)
+		v, changed := fastpathTV.DecMapIntBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapIntBoolV(rv2i(rv).(map[int]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, d *Decoder) {
+	v, changed := f.DecMapIntBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapIntBoolV(v map[int]bool, canChange bool,
+	d *Decoder) (_ map[int]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]interface{})
+		v, changed := fastpathTV.DecMapInt8IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8IntfV(rv2i(rv).(map[int8]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, d *Decoder) {
+	v, changed := f.DecMapInt8IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, canChange bool,
+	d *Decoder) (_ map[int8]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[int8]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk int8
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]string)
+		v, changed := fastpathTV.DecMapInt8StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8StringV(rv2i(rv).(map[int8]string), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, d *Decoder) {
+	v, changed := f.DecMapInt8StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8StringV(v map[int8]string, canChange bool,
+	d *Decoder) (_ map[int8]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[int8]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uint)
+		v, changed := fastpathTV.DecMapInt8UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8UintV(rv2i(rv).(map[int8]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, d *Decoder) {
+	v, changed := f.DecMapInt8UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, canChange bool,
+	d *Decoder) (_ map[int8]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uint8)
+		v, changed := fastpathTV.DecMapInt8Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Uint8V(rv2i(rv).(map[int8]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, d *Decoder) {
+	v, changed := f.DecMapInt8Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, canChange bool,
+	d *Decoder) (_ map[int8]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[int8]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uint16)
+		v, changed := fastpathTV.DecMapInt8Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Uint16V(rv2i(rv).(map[int8]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, d *Decoder) {
+	v, changed := f.DecMapInt8Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, canChange bool,
+	d *Decoder) (_ map[int8]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[int8]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uint32)
+		v, changed := fastpathTV.DecMapInt8Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Uint32V(rv2i(rv).(map[int8]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, d *Decoder) {
+	v, changed := f.DecMapInt8Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, canChange bool,
+	d *Decoder) (_ map[int8]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int8]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uint64)
+		v, changed := fastpathTV.DecMapInt8Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Uint64V(rv2i(rv).(map[int8]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, d *Decoder) {
+	v, changed := f.DecMapInt8Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, canChange bool,
+	d *Decoder) (_ map[int8]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]uintptr)
+		v, changed := fastpathTV.DecMapInt8UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8UintptrV(rv2i(rv).(map[int8]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8UintptrX(vp *map[int8]uintptr, d *Decoder) {
+	v, changed := f.DecMapInt8UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8UintptrV(v map[int8]uintptr, canChange bool,
+	d *Decoder) (_ map[int8]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]int)
+		v, changed := fastpathTV.DecMapInt8IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8IntV(rv2i(rv).(map[int8]int), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, d *Decoder) {
+	v, changed := f.DecMapInt8IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8IntV(v map[int8]int, canChange bool,
+	d *Decoder) (_ map[int8]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]int8)
+		v, changed := fastpathTV.DecMapInt8Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Int8V(rv2i(rv).(map[int8]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, d *Decoder) {
+	v, changed := f.DecMapInt8Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, canChange bool,
+	d *Decoder) (_ map[int8]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[int8]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]int16)
+		v, changed := fastpathTV.DecMapInt8Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Int16V(rv2i(rv).(map[int8]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, d *Decoder) {
+	v, changed := f.DecMapInt8Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, canChange bool,
+	d *Decoder) (_ map[int8]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[int8]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]int32)
+		v, changed := fastpathTV.DecMapInt8Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Int32V(rv2i(rv).(map[int8]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, d *Decoder) {
+	v, changed := f.DecMapInt8Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, canChange bool,
+	d *Decoder) (_ map[int8]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int8]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]int64)
+		v, changed := fastpathTV.DecMapInt8Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Int64V(rv2i(rv).(map[int8]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, d *Decoder) {
+	v, changed := f.DecMapInt8Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, canChange bool,
+	d *Decoder) (_ map[int8]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]float32)
+		v, changed := fastpathTV.DecMapInt8Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Float32V(rv2i(rv).(map[int8]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, d *Decoder) {
+	v, changed := f.DecMapInt8Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, canChange bool,
+	d *Decoder) (_ map[int8]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int8]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]float64)
+		v, changed := fastpathTV.DecMapInt8Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8Float64V(rv2i(rv).(map[int8]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, d *Decoder) {
+	v, changed := f.DecMapInt8Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, canChange bool,
+	d *Decoder) (_ map[int8]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int8]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt8BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int8]bool)
+		v, changed := fastpathTV.DecMapInt8BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt8BoolV(rv2i(rv).(map[int8]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, d *Decoder) {
+	v, changed := f.DecMapInt8BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, canChange bool,
+	d *Decoder) (_ map[int8]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[int8]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int8
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]interface{})
+		v, changed := fastpathTV.DecMapInt16IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16IntfV(rv2i(rv).(map[int16]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, d *Decoder) {
+	v, changed := f.DecMapInt16IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, canChange bool,
+	d *Decoder) (_ map[int16]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[int16]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk int16
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]string)
+		v, changed := fastpathTV.DecMapInt16StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16StringV(rv2i(rv).(map[int16]string), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, d *Decoder) {
+	v, changed := f.DecMapInt16StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16StringV(v map[int16]string, canChange bool,
+	d *Decoder) (_ map[int16]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 18)
+		v = make(map[int16]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uint)
+		v, changed := fastpathTV.DecMapInt16UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16UintV(rv2i(rv).(map[int16]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, d *Decoder) {
+	v, changed := f.DecMapInt16UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, canChange bool,
+	d *Decoder) (_ map[int16]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uint8)
+		v, changed := fastpathTV.DecMapInt16Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Uint8V(rv2i(rv).(map[int16]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, d *Decoder) {
+	v, changed := f.DecMapInt16Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, canChange bool,
+	d *Decoder) (_ map[int16]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[int16]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uint16)
+		v, changed := fastpathTV.DecMapInt16Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Uint16V(rv2i(rv).(map[int16]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, d *Decoder) {
+	v, changed := f.DecMapInt16Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, canChange bool,
+	d *Decoder) (_ map[int16]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		v = make(map[int16]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uint32)
+		v, changed := fastpathTV.DecMapInt16Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Uint32V(rv2i(rv).(map[int16]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, d *Decoder) {
+	v, changed := f.DecMapInt16Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, canChange bool,
+	d *Decoder) (_ map[int16]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[int16]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uint64)
+		v, changed := fastpathTV.DecMapInt16Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Uint64V(rv2i(rv).(map[int16]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, d *Decoder) {
+	v, changed := f.DecMapInt16Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, canChange bool,
+	d *Decoder) (_ map[int16]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]uintptr)
+		v, changed := fastpathTV.DecMapInt16UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16UintptrV(rv2i(rv).(map[int16]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16UintptrX(vp *map[int16]uintptr, d *Decoder) {
+	v, changed := f.DecMapInt16UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16UintptrV(v map[int16]uintptr, canChange bool,
+	d *Decoder) (_ map[int16]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]int)
+		v, changed := fastpathTV.DecMapInt16IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16IntV(rv2i(rv).(map[int16]int), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, d *Decoder) {
+	v, changed := f.DecMapInt16IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16IntV(v map[int16]int, canChange bool,
+	d *Decoder) (_ map[int16]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]int8)
+		v, changed := fastpathTV.DecMapInt16Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Int8V(rv2i(rv).(map[int16]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, d *Decoder) {
+	v, changed := f.DecMapInt16Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, canChange bool,
+	d *Decoder) (_ map[int16]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[int16]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]int16)
+		v, changed := fastpathTV.DecMapInt16Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Int16V(rv2i(rv).(map[int16]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, d *Decoder) {
+	v, changed := f.DecMapInt16Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, canChange bool,
+	d *Decoder) (_ map[int16]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 4)
+		v = make(map[int16]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]int32)
+		v, changed := fastpathTV.DecMapInt16Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Int32V(rv2i(rv).(map[int16]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, d *Decoder) {
+	v, changed := f.DecMapInt16Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, canChange bool,
+	d *Decoder) (_ map[int16]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[int16]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]int64)
+		v, changed := fastpathTV.DecMapInt16Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Int64V(rv2i(rv).(map[int16]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, d *Decoder) {
+	v, changed := f.DecMapInt16Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, canChange bool,
+	d *Decoder) (_ map[int16]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]float32)
+		v, changed := fastpathTV.DecMapInt16Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Float32V(rv2i(rv).(map[int16]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, d *Decoder) {
+	v, changed := f.DecMapInt16Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, canChange bool,
+	d *Decoder) (_ map[int16]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[int16]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]float64)
+		v, changed := fastpathTV.DecMapInt16Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16Float64V(rv2i(rv).(map[int16]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, d *Decoder) {
+	v, changed := f.DecMapInt16Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, canChange bool,
+	d *Decoder) (_ map[int16]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int16]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt16BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int16]bool)
+		v, changed := fastpathTV.DecMapInt16BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt16BoolV(rv2i(rv).(map[int16]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, d *Decoder) {
+	v, changed := f.DecMapInt16BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, canChange bool,
+	d *Decoder) (_ map[int16]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[int16]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int16
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]interface{})
+		v, changed := fastpathTV.DecMapInt32IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32IntfV(rv2i(rv).(map[int32]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, d *Decoder) {
+	v, changed := f.DecMapInt32IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, canChange bool,
+	d *Decoder) (_ map[int32]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[int32]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk int32
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]string)
+		v, changed := fastpathTV.DecMapInt32StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32StringV(rv2i(rv).(map[int32]string), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, d *Decoder) {
+	v, changed := f.DecMapInt32StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32StringV(v map[int32]string, canChange bool,
+	d *Decoder) (_ map[int32]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 20)
+		v = make(map[int32]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uint)
+		v, changed := fastpathTV.DecMapInt32UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32UintV(rv2i(rv).(map[int32]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, d *Decoder) {
+	v, changed := f.DecMapInt32UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, canChange bool,
+	d *Decoder) (_ map[int32]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uint8)
+		v, changed := fastpathTV.DecMapInt32Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Uint8V(rv2i(rv).(map[int32]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, d *Decoder) {
+	v, changed := f.DecMapInt32Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, canChange bool,
+	d *Decoder) (_ map[int32]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int32]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uint16)
+		v, changed := fastpathTV.DecMapInt32Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Uint16V(rv2i(rv).(map[int32]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, d *Decoder) {
+	v, changed := f.DecMapInt32Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, canChange bool,
+	d *Decoder) (_ map[int32]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[int32]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uint32)
+		v, changed := fastpathTV.DecMapInt32Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Uint32V(rv2i(rv).(map[int32]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, d *Decoder) {
+	v, changed := f.DecMapInt32Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, canChange bool,
+	d *Decoder) (_ map[int32]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[int32]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uint64)
+		v, changed := fastpathTV.DecMapInt32Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Uint64V(rv2i(rv).(map[int32]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, d *Decoder) {
+	v, changed := f.DecMapInt32Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, canChange bool,
+	d *Decoder) (_ map[int32]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]uintptr)
+		v, changed := fastpathTV.DecMapInt32UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32UintptrV(rv2i(rv).(map[int32]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32UintptrX(vp *map[int32]uintptr, d *Decoder) {
+	v, changed := f.DecMapInt32UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32UintptrV(v map[int32]uintptr, canChange bool,
+	d *Decoder) (_ map[int32]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]int)
+		v, changed := fastpathTV.DecMapInt32IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32IntV(rv2i(rv).(map[int32]int), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, d *Decoder) {
+	v, changed := f.DecMapInt32IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32IntV(v map[int32]int, canChange bool,
+	d *Decoder) (_ map[int32]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]int8)
+		v, changed := fastpathTV.DecMapInt32Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Int8V(rv2i(rv).(map[int32]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, d *Decoder) {
+	v, changed := f.DecMapInt32Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, canChange bool,
+	d *Decoder) (_ map[int32]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int32]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]int16)
+		v, changed := fastpathTV.DecMapInt32Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Int16V(rv2i(rv).(map[int32]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, d *Decoder) {
+	v, changed := f.DecMapInt32Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, canChange bool,
+	d *Decoder) (_ map[int32]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 6)
+		v = make(map[int32]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]int32)
+		v, changed := fastpathTV.DecMapInt32Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Int32V(rv2i(rv).(map[int32]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, d *Decoder) {
+	v, changed := f.DecMapInt32Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, canChange bool,
+	d *Decoder) (_ map[int32]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[int32]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]int64)
+		v, changed := fastpathTV.DecMapInt32Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Int64V(rv2i(rv).(map[int32]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, d *Decoder) {
+	v, changed := f.DecMapInt32Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, canChange bool,
+	d *Decoder) (_ map[int32]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]float32)
+		v, changed := fastpathTV.DecMapInt32Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Float32V(rv2i(rv).(map[int32]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, d *Decoder) {
+	v, changed := f.DecMapInt32Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, canChange bool,
+	d *Decoder) (_ map[int32]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 8)
+		v = make(map[int32]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]float64)
+		v, changed := fastpathTV.DecMapInt32Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32Float64V(rv2i(rv).(map[int32]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, d *Decoder) {
+	v, changed := f.DecMapInt32Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, canChange bool,
+	d *Decoder) (_ map[int32]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int32]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt32BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int32]bool)
+		v, changed := fastpathTV.DecMapInt32BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt32BoolV(rv2i(rv).(map[int32]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, d *Decoder) {
+	v, changed := f.DecMapInt32BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, canChange bool,
+	d *Decoder) (_ map[int32]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[int32]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int32
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64IntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]interface{})
+		v, changed := fastpathTV.DecMapInt64IntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64IntfV(rv2i(rv).(map[int64]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, d *Decoder) {
+	v, changed := f.DecMapInt64IntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, canChange bool,
+	d *Decoder) (_ map[int64]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[int64]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk int64
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64StringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]string)
+		v, changed := fastpathTV.DecMapInt64StringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64StringV(rv2i(rv).(map[int64]string), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, d *Decoder) {
+	v, changed := f.DecMapInt64StringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64StringV(v map[int64]string, canChange bool,
+	d *Decoder) (_ map[int64]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 24)
+		v = make(map[int64]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64UintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uint)
+		v, changed := fastpathTV.DecMapInt64UintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64UintV(rv2i(rv).(map[int64]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, d *Decoder) {
+	v, changed := f.DecMapInt64UintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, canChange bool,
+	d *Decoder) (_ map[int64]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Uint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uint8)
+		v, changed := fastpathTV.DecMapInt64Uint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Uint8V(rv2i(rv).(map[int64]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, d *Decoder) {
+	v, changed := f.DecMapInt64Uint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, canChange bool,
+	d *Decoder) (_ map[int64]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int64]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Uint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uint16)
+		v, changed := fastpathTV.DecMapInt64Uint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Uint16V(rv2i(rv).(map[int64]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, d *Decoder) {
+	v, changed := f.DecMapInt64Uint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, canChange bool,
+	d *Decoder) (_ map[int64]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int64]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Uint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uint32)
+		v, changed := fastpathTV.DecMapInt64Uint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Uint32V(rv2i(rv).(map[int64]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, d *Decoder) {
+	v, changed := f.DecMapInt64Uint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, canChange bool,
+	d *Decoder) (_ map[int64]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int64]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Uint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uint64)
+		v, changed := fastpathTV.DecMapInt64Uint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Uint64V(rv2i(rv).(map[int64]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, d *Decoder) {
+	v, changed := f.DecMapInt64Uint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, canChange bool,
+	d *Decoder) (_ map[int64]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64UintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]uintptr)
+		v, changed := fastpathTV.DecMapInt64UintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64UintptrV(rv2i(rv).(map[int64]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64UintptrX(vp *map[int64]uintptr, d *Decoder) {
+	v, changed := f.DecMapInt64UintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64UintptrV(v map[int64]uintptr, canChange bool,
+	d *Decoder) (_ map[int64]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64IntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]int)
+		v, changed := fastpathTV.DecMapInt64IntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64IntV(rv2i(rv).(map[int64]int), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, d *Decoder) {
+	v, changed := f.DecMapInt64IntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64IntV(v map[int64]int, canChange bool,
+	d *Decoder) (_ map[int64]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Int8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]int8)
+		v, changed := fastpathTV.DecMapInt64Int8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Int8V(rv2i(rv).(map[int64]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, d *Decoder) {
+	v, changed := f.DecMapInt64Int8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, canChange bool,
+	d *Decoder) (_ map[int64]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int64]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Int16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]int16)
+		v, changed := fastpathTV.DecMapInt64Int16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Int16V(rv2i(rv).(map[int64]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, d *Decoder) {
+	v, changed := f.DecMapInt64Int16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, canChange bool,
+	d *Decoder) (_ map[int64]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 10)
+		v = make(map[int64]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Int32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]int32)
+		v, changed := fastpathTV.DecMapInt64Int32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Int32V(rv2i(rv).(map[int64]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, d *Decoder) {
+	v, changed := f.DecMapInt64Int32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, canChange bool,
+	d *Decoder) (_ map[int64]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int64]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Int64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]int64)
+		v, changed := fastpathTV.DecMapInt64Int64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Int64V(rv2i(rv).(map[int64]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, d *Decoder) {
+	v, changed := f.DecMapInt64Int64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, canChange bool,
+	d *Decoder) (_ map[int64]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Float32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]float32)
+		v, changed := fastpathTV.DecMapInt64Float32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Float32V(rv2i(rv).(map[int64]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, d *Decoder) {
+	v, changed := f.DecMapInt64Float32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, canChange bool,
+	d *Decoder) (_ map[int64]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 12)
+		v = make(map[int64]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64Float64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]float64)
+		v, changed := fastpathTV.DecMapInt64Float64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64Float64V(rv2i(rv).(map[int64]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, d *Decoder) {
+	v, changed := f.DecMapInt64Float64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, canChange bool,
+	d *Decoder) (_ map[int64]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 16)
+		v = make(map[int64]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapInt64BoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[int64]bool)
+		v, changed := fastpathTV.DecMapInt64BoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapInt64BoolV(rv2i(rv).(map[int64]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, d *Decoder) {
+	v, changed := f.DecMapInt64BoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, canChange bool,
+	d *Decoder) (_ map[int64]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[int64]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk int64
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeInt64()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolIntfR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]interface{})
+		v, changed := fastpathTV.DecMapBoolIntfV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolIntfV(rv2i(rv).(map[bool]interface{}), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, d *Decoder) {
+	v, changed := f.DecMapBoolIntfV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, canChange bool,
+	d *Decoder) (_ map[bool]interface{}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[bool]interface{}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+	var mk bool
+	var mv interface{}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = nil
+			}
+			continue
+		}
+		if mapGet {
+			mv = v[mk]
+		} else {
+			mv = nil
+		}
+		d.decode(&mv)
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolStringR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]string)
+		v, changed := fastpathTV.DecMapBoolStringV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolStringV(rv2i(rv).(map[bool]string), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, d *Decoder) {
+	v, changed := f.DecMapBoolStringV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolStringV(v map[bool]string, canChange bool,
+	d *Decoder) (_ map[bool]string, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 17)
+		v = make(map[bool]string, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv string
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = ""
+			}
+			continue
+		}
+		mv = dd.DecodeString()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUintR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uint)
+		v, changed := fastpathTV.DecMapBoolUintV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUintV(rv2i(rv).(map[bool]uint), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, d *Decoder) {
+	v, changed := f.DecMapBoolUintV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, canChange bool,
+	d *Decoder) (_ map[bool]uint, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]uint, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uint
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUint8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uint8)
+		v, changed := fastpathTV.DecMapBoolUint8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUint8V(rv2i(rv).(map[bool]uint8), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, d *Decoder) {
+	v, changed := f.DecMapBoolUint8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, canChange bool,
+	d *Decoder) (_ map[bool]uint8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[bool]uint8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uint8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint8(chkOvf.UintV(dd.DecodeUint64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUint16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uint16)
+		v, changed := fastpathTV.DecMapBoolUint16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUint16V(rv2i(rv).(map[bool]uint16), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, d *Decoder) {
+	v, changed := f.DecMapBoolUint16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, canChange bool,
+	d *Decoder) (_ map[bool]uint16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[bool]uint16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uint16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint16(chkOvf.UintV(dd.DecodeUint64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUint32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uint32)
+		v, changed := fastpathTV.DecMapBoolUint32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUint32V(rv2i(rv).(map[bool]uint32), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, d *Decoder) {
+	v, changed := f.DecMapBoolUint32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, canChange bool,
+	d *Decoder) (_ map[bool]uint32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[bool]uint32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uint32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uint32(chkOvf.UintV(dd.DecodeUint64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUint64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uint64)
+		v, changed := fastpathTV.DecMapBoolUint64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUint64V(rv2i(rv).(map[bool]uint64), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, d *Decoder) {
+	v, changed := f.DecMapBoolUint64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, canChange bool,
+	d *Decoder) (_ map[bool]uint64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]uint64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uint64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeUint64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolUintptrR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]uintptr)
+		v, changed := fastpathTV.DecMapBoolUintptrV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolUintptrV(rv2i(rv).(map[bool]uintptr), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolUintptrX(vp *map[bool]uintptr, d *Decoder) {
+	v, changed := f.DecMapBoolUintptrV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolUintptrV(v map[bool]uintptr, canChange bool,
+	d *Decoder) (_ map[bool]uintptr, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]uintptr, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv uintptr
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolIntR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]int)
+		v, changed := fastpathTV.DecMapBoolIntV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolIntV(rv2i(rv).(map[bool]int), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, d *Decoder) {
+	v, changed := f.DecMapBoolIntV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolIntV(v map[bool]int, canChange bool,
+	d *Decoder) (_ map[bool]int, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]int, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv int
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolInt8R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]int8)
+		v, changed := fastpathTV.DecMapBoolInt8V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolInt8V(rv2i(rv).(map[bool]int8), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, d *Decoder) {
+	v, changed := f.DecMapBoolInt8V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, canChange bool,
+	d *Decoder) (_ map[bool]int8, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[bool]int8, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv int8
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int8(chkOvf.IntV(dd.DecodeInt64(), 8))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolInt16R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]int16)
+		v, changed := fastpathTV.DecMapBoolInt16V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolInt16V(rv2i(rv).(map[bool]int16), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, d *Decoder) {
+	v, changed := f.DecMapBoolInt16V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, canChange bool,
+	d *Decoder) (_ map[bool]int16, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 3)
+		v = make(map[bool]int16, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv int16
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int16(chkOvf.IntV(dd.DecodeInt64(), 16))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolInt32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]int32)
+		v, changed := fastpathTV.DecMapBoolInt32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolInt32V(rv2i(rv).(map[bool]int32), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, d *Decoder) {
+	v, changed := f.DecMapBoolInt32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, canChange bool,
+	d *Decoder) (_ map[bool]int32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[bool]int32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv int32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = int32(chkOvf.IntV(dd.DecodeInt64(), 32))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolInt64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]int64)
+		v, changed := fastpathTV.DecMapBoolInt64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolInt64V(rv2i(rv).(map[bool]int64), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, d *Decoder) {
+	v, changed := f.DecMapBoolInt64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, canChange bool,
+	d *Decoder) (_ map[bool]int64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]int64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv int64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeInt64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolFloat32R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]float32)
+		v, changed := fastpathTV.DecMapBoolFloat32V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolFloat32V(rv2i(rv).(map[bool]float32), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, d *Decoder) {
+	v, changed := f.DecMapBoolFloat32V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, canChange bool,
+	d *Decoder) (_ map[bool]float32, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 5)
+		v = make(map[bool]float32, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv float32
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = float32(chkOvf.Float32V(dd.DecodeFloat64()))
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolFloat64R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]float64)
+		v, changed := fastpathTV.DecMapBoolFloat64V(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolFloat64V(rv2i(rv).(map[bool]float64), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, d *Decoder) {
+	v, changed := f.DecMapBoolFloat64V(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, canChange bool,
+	d *Decoder) (_ map[bool]float64, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 9)
+		v = make(map[bool]float64, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv float64
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = 0
+			}
+			continue
+		}
+		mv = dd.DecodeFloat64()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+
+func (d *Decoder) fastpathDecMapBoolBoolR(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[bool]bool)
+		v, changed := fastpathTV.DecMapBoolBoolV(*vp, true, d)
+		if changed {
+			*vp = v
+		}
+	} else {
+		fastpathTV.DecMapBoolBoolV(rv2i(rv).(map[bool]bool), false, d)
+	}
+}
+func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, d *Decoder) {
+	v, changed := f.DecMapBoolBoolV(*vp, true, d)
+	if changed {
+		*vp = v
+	}
+}
+func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, canChange bool,
+	d *Decoder) (_ map[bool]bool, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators()
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, 2)
+		v = make(map[bool]bool, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	var mk bool
+	var mv bool
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep {
+			dd.ReadMapElemKey()
+		}
+		mk = dd.DecodeBool()
+		if esep {
+			dd.ReadMapElemValue()
+		}
+		if dd.TryDecodeAsNil() {
+			if v == nil {
+			} else if d.h.DeleteOnNilMapValue {
+				delete(v, mk)
+			} else {
+				v[mk] = false
+			}
+			continue
+		}
+		mv = dd.DecodeBool()
+		if v != nil {
+			v[mk] = mv
+		}
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
new file mode 100644
index 0000000..2023e05
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
@@ -0,0 +1,544 @@
+// +build !notfastpath
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from fast-path.go.tmpl - DO NOT EDIT.
+
+package codec
+
+// Fast path functions try to create a fast path encode or decode implementation
+// for common maps and slices.
+//
+// We define the functions and register then in this single file
+// so as not to pollute the encode.go and decode.go, and create a dependency in there.
+// This file can be omitted without causing a build failure.
+//
+// The advantage of fast paths is:
+//	  - Many calls bypass reflection altogether
+// 
+// Currently support
+//	  - slice of all builtin types,
+//	  - map of all builtin types to string or interface value
+//	  - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
+// This should provide adequate "typical" implementations.
+// 
+// Note that fast track decode functions must handle values for which an address cannot be obtained.
+// For example: 
+//	 m2 := map[string]int{}
+//	 p2 := []interface{}{m2}
+//	 // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
+// 
+
+import (
+	"reflect"
+	"sort"
+)
+
+const fastpathEnabled = true
+
+type fastpathT struct {}
+
+var fastpathTV fastpathT
+
+type fastpathE struct {
+	rtid uintptr
+	rt reflect.Type 
+	encfn func(*Encoder, *codecFnInfo, reflect.Value)
+	decfn func(*Decoder, *codecFnInfo, reflect.Value)
+}
+
+type fastpathA [{{ .FastpathLen }}]fastpathE
+
+func (x *fastpathA) index(rtid uintptr) int {
+	// use binary search to grab the index (adapted from sort/search.go)
+	h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
+	for i < j {
+		h = i + (j-i)/2
+		if x[h].rtid < rtid {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	if i < {{ .FastpathLen }} && x[i].rtid == rtid {
+		return i
+	}
+	return -1
+}
+
+type fastpathAslice []fastpathE
+
+func (x fastpathAslice) Len() int { return len(x) }
+func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
+func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+var fastpathAV fastpathA
+
+// due to possible initialization loop error, make fastpath in an init()
+func init() {
+	i := 0
+	fn := func(v interface{},
+		fe func(*Encoder, *codecFnInfo, reflect.Value),
+		fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
+		xrt := reflect.TypeOf(v)
+		xptr := rt2id(xrt)
+		fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
+		i++
+		return
+	}
+	{{/* do not register []uint8 in fast-path */}}
+	{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
+	fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
+	
+	{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
+	
+	sort.Sort(fastpathAslice(fastpathAV[:]))
+}
+
+// -- encode
+
+// -- -- fast path type switch
+func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
+	case []{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
+	case *[]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
+*/}}{{end}}{{end}}{{end}}{{end}}
+
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	case map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
+	case *map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
+*/}}{{end}}{{end}}{{end}}
+
+	default:
+        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+{{/*
+**** removing this block, as they are never called directly ****
+
+
+
+**** removing this block, as they are never called directly ****
+
+
+
+func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	case []{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
+	case *[]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
+{{end}}{{end}}{{end}}
+	default:
+        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	case map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
+	case *map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
+{{end}}{{end}}{{end}}
+	default:
+        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+
+
+**** removing this block, as they are never called directly ****
+
+
+
+**** removing this block, as they are never called directly ****
+*/}}
+
+// -- -- fast path functions
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} 
+func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
+	if f.ti.mbs {
+		fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
+	} else {
+		fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).([]{{ .Elem }}), e)
+	}
+}
+func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
+	if v == nil { e.e.EncodeNil(); return }
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	ee.WriteArrayStart(len(v))
+	if esep {
+		for _, v2 := range v {
+			ee.WriteArrayElem()
+			{{ encmd .Elem "v2"}}
+		}
+	} else {
+		for _, v2 := range v {
+			{{ encmd .Elem "v2"}}
+		}
+	} {{/*
+	for _, v2 := range v {
+		if esep { ee.WriteArrayElem() }
+		{{ encmd .Elem "v2"}}
+	} */}}
+	ee.WriteArrayEnd()
+}
+func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
+	ee, esep := e.e, e.hh.hasElemSeparators()
+	if len(v)%2 == 1 {
+		e.errorf("mapBySlice requires even slice length, but got %v", len(v))
+		return
+	}
+	ee.WriteMapStart(len(v) / 2)
+	if esep {
+		for j, v2 := range v {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+			{{ encmd .Elem "v2"}}
+		}
+	} else {
+		for _, v2 := range v {
+			{{ encmd .Elem "v2"}}
+		}
+	} {{/*
+	for j, v2 := range v {
+		if esep {
+			if j%2 == 0 {
+				ee.WriteMapElemKey()
+			} else {
+				ee.WriteMapElemValue()
+			}
+		}
+		{{ encmd .Elem "v2"}}
+	} */}}
+	ee.WriteMapEnd()
+}
+{{end}}{{end}}{{end}}
+
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
+	fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
+}
+func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
+	if v == nil { e.e.EncodeNil(); return }
+	ee, esep := e.e, e.hh.hasElemSeparators() 
+	ee.WriteMapStart(len(v))
+	if e.h.Canonical {
+		{{if eq .MapKey "interface{}"}}{{/* out of band 
+		*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
+		e2 := NewEncoderBytes(&mksv, e.hh)
+		v2 := make([]bytesI, len(v))
+		var i, l int
+		var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
+		for k2, _ := range v {
+			l = len(mksv)
+			e2.MustEncode(k2)
+			vp = &v2[i]
+			vp.v = mksv[l:]
+			vp.i = k2 
+			i++
+		}
+		sort.Sort(bytesISlice(v2))
+		if esep {
+			for j := range v2 {
+				ee.WriteMapElemKey()
+				e.asis(v2[j].v)
+				ee.WriteMapElemValue()
+				e.encode(v[v2[j].i])
+			}
+		} else {
+			for j := range v2 {
+				e.asis(v2[j].v)
+				e.encode(v[v2[j].i])
+			}
+		} {{/*
+		for j := range v2 {
+			if esep { ee.WriteMapElemKey() }
+			e.asis(v2[j].v)
+			if esep { ee.WriteMapElemValue() }
+			e.encode(v[v2[j].i])
+		} */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
+		var i int 
+		for k, _ := range v {
+			v2[i] = {{ $x }}(k)
+			i++
+		}
+		sort.Sort({{ sorttype .MapKey false}}(v2))
+		if esep {
+			for _, k2 := range v2 {
+				ee.WriteMapElemKey()
+				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
+				ee.WriteMapElemValue()
+				{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
+			} 
+		} else {
+			for _, k2 := range v2 {
+				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
+				{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
+			} 
+		} {{/*
+		for _, k2 := range v2 {
+			if esep { ee.WriteMapElemKey() }
+			{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
+			if esep { ee.WriteMapElemValue() }
+			{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
+		} */}} {{end}}
+	} else {
+		if esep {
+			for k2, v2 := range v {
+				ee.WriteMapElemKey()
+				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
+				ee.WriteMapElemValue()
+				{{ encmd .Elem "v2"}}
+			}
+		} else {
+			for k2, v2 := range v {
+				{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
+				{{ encmd .Elem "v2"}}
+			}
+		} {{/*
+		for k2, v2 := range v {
+			if esep { ee.WriteMapElemKey() }
+			{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
+			if esep { ee.WriteMapElemValue() }
+			{{ encmd .Elem "v2"}}
+		} */}}
+	}
+	ee.WriteMapEnd()
+}
+{{end}}{{end}}{{end}}
+
+// -- decode
+
+// -- -- fast path type switch
+func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
+     var changed bool
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
+	case []{{ .Elem }}:
+        var v2 []{{ .Elem }}
+		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
+        if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+			copy(v, v2)
+		}
+	case *[]{{ .Elem }}:
+        var v2 []{{ .Elem }}
+		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
+        if changed {
+			*v = v2 
+		}{{/*
+*/}}{{end}}{{end}}{{end}}{{end}}
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
+// maps only change if nil, and in that case, there's no point copying
+*/}}
+	case map[{{ .MapKey }}]{{ .Elem }}:
+		fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
+	case *map[{{ .MapKey }}]{{ .Elem }}:
+         var v2 map[{{ .MapKey }}]{{ .Elem }}
+		v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
+        if changed {
+			*v = v2 
+		}{{/*
+*/}}{{end}}{{end}}{{end}}
+	default:
+        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
+	switch v := iv.(type) {
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+	case *[]{{ .Elem }}: 
+		*v = nil {{/*
+*/}}{{end}}{{end}}{{end}}
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+	case *map[{{ .MapKey }}]{{ .Elem }}: 
+		*v = nil {{/*
+*/}}{{end}}{{end}}{{end}}
+	default:
+        _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
+		return false
+	}
+	return true
+}
+
+// -- -- fast path functions
+{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
+{{/*
+Slices can change if they 
+- did not come from an array
+- are addressable (from a ptr)
+- are settable (e.g. contained in an interface{})
+*/}}
+func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
+	if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*[]{{ .Elem }})
+		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
+        if changed { *vp = v }
+	} else {
+		v := rv2i(rv).([]{{ .Elem }})
+        v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
+        if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
+           copy(v, v2)
+        }
+	}
+}
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
+	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
+    if changed { *vp = v }
+}
+func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
+	dd := d.d{{/*
+	    // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
+    */}}
+	slh, containerLenS := d.decSliceHelperStart()
+	if containerLenS == 0 {
+		if canChange {
+			if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
+			changed = true
+		}
+		slh.End()
+		return v, changed
+	}
+	hasLen := containerLenS > 0
+	var xlen int 
+	if hasLen && canChange {
+		if containerLenS > cap(v) {
+			xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
+			if xlen <= cap(v) {
+				v = v[:xlen]
+			} else {
+				v = make([]{{ .Elem }}, xlen)
+			}
+			changed = true 
+		} else if containerLenS != len(v) {
+			v = v[:containerLenS]
+			changed = true
+		}
+	}
+	j := 0
+	for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
+		if j == 0 && len(v) == 0 && canChange {
+			if hasLen {
+				xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
+			} else {
+				xlen = 8
+			}
+			v = make([]{{ .Elem }}, xlen)
+			changed = true 
+		}
+		// if indefinite, etc, then expand the slice if necessary
+		var decodeIntoBlank bool
+		if j >= len(v) {
+			if canChange {
+				v = append(v, {{ zerocmd .Elem }})
+				changed = true
+			} else {
+				d.arrayCannotExpand(len(v), j+1)
+				decodeIntoBlank = true
+			}
+		} 
+		slh.ElemContainerState(j)
+		if decodeIntoBlank {
+			d.swallow()
+		} else if dd.TryDecodeAsNil() {
+			v[j] = {{ zerocmd .Elem }}
+		} else {
+			{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
+		}
+	}
+	if canChange {
+		if j < len(v) {
+			v = v[:j]
+			changed = true
+		} else if j == 0 && v == nil {
+			v = make([]{{ .Elem }}, 0)
+			changed = true
+		}
+	}
+	slh.End()
+	return v, changed 
+}
+{{end}}{{end}}{{end}}
+
+{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
+{{/*
+Maps can change if they are
+- addressable (from a ptr)
+- settable (e.g. contained in an interface{})
+*/}}
+func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
+	if rv.Kind() == reflect.Ptr {
+		vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
+		v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
+		if changed { *vp = v }
+	} else {
+	    fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
+    }
+}
+func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
+	v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
+	if changed { *vp = v }
+}
+func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool, 
+	d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
+	dd, esep := d.d, d.hh.hasElemSeparators(){{/*
+	    // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
+    */}}
+	containerLen := dd.ReadMapStart()
+	if canChange && v == nil {
+		xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
+		v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
+		changed = true
+	}
+	if containerLen == 0 {
+		dd.ReadMapEnd()
+		return v, changed
+	}
+	{{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
+    {{end}}var mk {{ .MapKey }}
+	var mv {{ .Elem }}
+	hasLen := containerLen > 0
+	for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
+		if esep { dd.ReadMapElemKey() }
+		{{ if eq .MapKey "interface{}" }}mk = nil 
+		d.decode(&mk)
+		if bv, bok := mk.([]byte); bok {
+			mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
+		}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
+		if esep { dd.ReadMapElemValue() }
+		if dd.TryDecodeAsNil() {
+			if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
+			continue 
+		}
+		{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
+		d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
+		if v != nil { v[mk] = mv }
+	}
+	dd.ReadMapEnd()
+	return v, changed
+}
+{{end}}{{end}}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/fast-path.not.go b/vendor/github.com/ugorji/go/codec/fast-path.not.go
new file mode 100644
index 0000000..f11b467
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/fast-path.not.go
@@ -0,0 +1,47 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build notfastpath
+
+package codec
+
+import "reflect"
+
+const fastpathEnabled = false
+
+// The generated fast-path code is very large, and adds a few seconds to the build time.
+// This causes test execution, execution of small tools which use codec, etc
+// to take a long time.
+//
+// To mitigate, we now support the notfastpath tag.
+// This tag disables fastpath during build, allowing for faster build, test execution,
+// short-program runs, etc.
+
+func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool      { return false }
+func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool      { return false }
+func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
+func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool   { return false }
+func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool           { return false }
+
+type fastpathT struct{}
+type fastpathE struct {
+	rtid  uintptr
+	rt    reflect.Type
+	encfn func(*Encoder, *codecFnInfo, reflect.Value)
+	decfn func(*Decoder, *codecFnInfo, reflect.Value)
+}
+type fastpathA [0]fastpathE
+
+func (x fastpathA) index(rtid uintptr) int { return -1 }
+
+func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
+	fn := d.cfer().get(uint8SliceTyp, true, true)
+	d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
+	return v, true
+}
+
+var fastpathAV fastpathA
+var fastpathTV fastpathT
+
+// ----
+type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
new file mode 100644
index 0000000..59c5983
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
@@ -0,0 +1,78 @@
+{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
+var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
+if {{var "l"}} == 0 {
+	{{if isSlice }}if {{var "v"}} == nil {
+		{{var "v"}} = []{{ .Typ }}{}
+		{{var "c"}} = true
+	} else if len({{var "v"}}) != 0 {
+		{{var "v"}} = {{var "v"}}[:0]
+		{{var "c"}} = true
+	} {{else if isChan }}if {{var "v"}} == nil {
+		{{var "v"}} = make({{ .CTyp }}, 0)
+		{{var "c"}} = true
+	} {{end}}
+} else {
+	{{var "hl"}} := {{var "l"}} > 0
+	var {{var "rl"}} int
+	_ =  {{var "rl"}}
+	{{if isSlice }} if {{var "hl"}} {
+	if {{var "l"}} > cap({{var "v"}}) {
+		{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		if {{var "rl"}} <= cap({{var "v"}}) {
+			{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
+		} else {
+			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
+		}
+		{{var "c"}} = true
+	} else if {{var "l"}} != len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
+		{{var "c"}} = true
+	}
+	} {{end}}
+	var {{var "j"}} int 
+    // var {{var "dn"}} bool 
+	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
+		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
+			if {{var "hl"}} {
+				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+			} else {
+				{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
+			}
+			{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
+			{{var "c"}} = true 
+		}{{end}}
+		{{var "h"}}.ElemContainerState({{var "j"}})
+        {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
+        {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
+		{{ decLineVar $x }}
+		{{var "v"}} <- {{ $x }}
+        // println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
+        {{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
+		var {{var "db"}} bool
+		if {{var "j"}} >= len({{var "v"}}) {
+			{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
+			{{var "c"}} = true
+			{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
+			{{end}}
+		}
+		if {{var "db"}} {
+			z.DecSwallow()
+		} else {
+			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		}
+        {{end}}
+	}
+	{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
+		{{var "c"}} = true
+	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
+		{{var "v"}} = make([]{{ .Typ }}, 0)
+		{{var "c"}} = true
+	} {{end}}
+}
+{{var "h"}}.End()
+{{if not isArray }}if {{var "c"}} { 
+	*{{ .Varname }} = {{var "v"}}
+}{{end}}
diff --git a/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
new file mode 100644
index 0000000..8323b54
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
@@ -0,0 +1,42 @@
+{{var "v"}} := *{{ .Varname }}
+{{var "l"}} := r.ReadMapStart()
+{{var "bh"}} := z.DecBasicHandle()
+if {{var "v"}} == nil {
+	{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
+	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
+	*{{ .Varname }} = {{var "v"}}
+}
+var {{var "mk"}} {{ .KTyp }}
+var {{var "mv"}} {{ .Typ }}
+var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
+if {{var "bh"}}.MapValueReset {
+	{{if decElemKindPtr}}{{var "mg"}} = true
+	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
+	{{else if not decElemKindImmutable}}{{var "mg"}} = true
+	{{end}} }
+if {{var "l"}} != 0 {
+{{var "hl"}} := {{var "l"}} > 0 
+	for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
+	r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
+	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
+{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
+		{{var "mk"}} = string({{var "bv"}})
+	}{{ end }}{{if decElemKindPtr}}
+	{{var "ms"}} = true{{end}}
+	if {{var "mg"}} {
+		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
+		if {{var "mok"}} {
+			{{var "ms"}} = false
+		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
+	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
+	r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
+	{{var "mdn"}} = false
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
+	if {{var "mdn"}} {
+		if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
+	} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
+	}
+}
+} // else len==0: TODO: Should we clear map entries?
+r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
diff --git a/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
new file mode 100644
index 0000000..4249588
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
@@ -0,0 +1,27 @@
+{{.Label}}:
+switch timeout{{.Sfx}} :=  z.EncBasicHandle().ChanRecvTimeout; {
+case timeout{{.Sfx}} == 0: // only consume available
+	for {
+		select {
+		case b{{.Sfx}} := <-{{.Chan}}:
+			{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
+		default:
+			break {{.Label}}
+		}
+	}
+case timeout{{.Sfx}} > 0: // consume until timeout
+	tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
+	for {
+		select {
+		case b{{.Sfx}} := <-{{.Chan}}:
+			{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
+		case <-tt{{.Sfx}}.C:
+			// close(tt.C)
+			break {{.Label}}
+		}
+	}
+default: // consume until close
+	for b{{.Sfx}} := range {{.Chan}} {
+		{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
+	}
+}
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.generated.go b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
new file mode 100644
index 0000000..917d282
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-helper.generated.go
@@ -0,0 +1,335 @@
+/* // +build ignore */
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
+
+package codec
+
+import (
+	"encoding"
+	"reflect"
+)
+
+// GenVersion is the current version of codecgen.
+const GenVersion = 8
+
+// This file is used to generate helper code for codecgen.
+// The values here i.e. genHelper(En|De)coder are not to be used directly by
+// library users. They WILL change continuously and without notice.
+//
+// To help enforce this, we create an unexported type with exported members.
+// The only way to get the type is via the one exported type that we control (somewhat).
+//
+// When static codecs are created for types, they will use this value
+// to perform encoding or decoding of primitives or known slice or map types.
+
+// GenHelperEncoder is exported so that it can be used externally by codecgen.
+//
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
+	ge = genHelperEncoder{e: e}
+	ee = genHelperEncDriver{encDriver: e.e}
+	return
+}
+
+// GenHelperDecoder is exported so that it can be used externally by codecgen.
+//
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
+	gd = genHelperDecoder{d: d}
+	dd = genHelperDecDriver{decDriver: d.d}
+	return
+}
+
+type genHelperEncDriver struct {
+	encDriver
+}
+
+func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
+func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
+	encStructFieldKey(x.encDriver, keyType, s)
+}
+func (x genHelperEncDriver) EncodeSymbol(s string) {
+	x.encDriver.EncodeString(cUTF8, s)
+}
+
+type genHelperDecDriver struct {
+	decDriver
+	C checkOverflow
+}
+
+func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
+func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
+	return decStructFieldKey(x.decDriver, keyType, buf)
+}
+func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
+	return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
+}
+func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
+	return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
+}
+func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
+	f = x.DecodeFloat64()
+	if chkOverflow32 && chkOvf.Float32(f) {
+		panicv.errorf("float32 overflow: %v", f)
+	}
+	return
+}
+func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
+	f = x.DecodeFloat64()
+	if chkOvf.Float32(f) {
+		panicv.errorf("float32 overflow: %v", f)
+	}
+	return
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperEncoder struct {
+	M must
+	e *Encoder
+	F fastpathT
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperDecoder struct {
+	C checkOverflow
+	d *Decoder
+	F fastpathT
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
+	return f.e.h
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinary() bool {
+	return f.e.be // f.e.hh.isBinaryEncoding()
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) IsJSONHandle() bool {
+	return f.e.js
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncFallback(iv interface{}) {
+	// println(">>>>>>>>> EncFallback")
+	// f.e.encodeI(iv, false, false)
+	f.e.encodeValue(reflect.ValueOf(iv), nil, false)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
+	bs, fnerr := iv.MarshalText()
+	f.e.marshal(bs, fnerr, false, cUTF8)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
+	bs, fnerr := iv.MarshalJSON()
+	f.e.marshal(bs, fnerr, true, cUTF8)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
+	bs, fnerr := iv.MarshalBinary()
+	f.e.marshal(bs, fnerr, false, cRAW)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: builtin no longer supported - so we make this method a no-op,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
+
+// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
+// 	if _, ok := f.e.hh.(*BincHandle); ok {
+// 		return timeTypId
+// 	}
+// }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
+	return i2rtid(v)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
+	return f.e.h.getExt(rtid)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
+	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) HasExtensions() bool {
+	return len(f.e.h.extHandle) != 0
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
+	if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
+		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+		return true
+	}
+	return false
+}
+
+// ---------------- DECODER FOLLOWS -----------------
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
+	return f.d.h
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinary() bool {
+	return f.d.be // f.d.hh.isBinaryEncoding()
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecScratchBuffer() []byte {
+	return f.d.b[:]
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
+	return &f.d.b
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
+	// println(">>>>>>>>> DecFallback")
+	rv := reflect.ValueOf(iv)
+	if chkPtr {
+		rv = f.d.ensureDecodeable(rv)
+	}
+	f.d.decodeValue(rv, nil, false)
+	// f.d.decodeValueFallback(rv)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
+	return f.d.decSliceHelperStart()
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
+	f.d.structFieldNotFound(index, name)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
+	f.d.arrayCannotExpand(sliceLen, streamLen)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
+	fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
+	// bs := f.dd.DecodeStringAsBytes()
+	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
+	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
+	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: builtin no longer supported - so we make this method a no-op,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
+
+// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
+// 	// Note: builtin is no longer supported - so make this a no-op
+// 	if _, ok := f.d.hh.(*BincHandle); ok {
+// 		return timeTypId
+// 	}
+// 	return 0
+// }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) IsJSONHandle() bool {
+	return f.d.js
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
+	return i2rtid(v)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
+	return f.d.h.getExt(rtid)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
+	f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) HasExtensions() bool {
+	return len(f.d.h.extHandle) != 0
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
+	if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
+		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+		return true
+	}
+	return false
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
+	return decInferLen(clen, maxlen, unit)
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: no longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
diff --git a/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl b/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
new file mode 100644
index 0000000..6aeb856
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
@@ -0,0 +1,302 @@
+/* // +build ignore */
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
+
+package codec
+
+import (
+	"encoding"
+	"reflect"
+)
+
+// GenVersion is the current version of codecgen.
+const GenVersion = {{ .Version }} 
+
+// This file is used to generate helper code for codecgen. 
+// The values here i.e. genHelper(En|De)coder are not to be used directly by 
+// library users. They WILL change continuously and without notice.
+//
+// To help enforce this, we create an unexported type with exported members.
+// The only way to get the type is via the one exported type that we control (somewhat).
+//
+// When static codecs are created for types, they will use this value
+// to perform encoding or decoding of primitives or known slice or map types.
+
+// GenHelperEncoder is exported so that it can be used externally by codecgen.
+//
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
+	ge = genHelperEncoder{e: e}
+	ee = genHelperEncDriver{encDriver: e.e}
+	return 
+}
+
+// GenHelperDecoder is exported so that it can be used externally by codecgen.
+//
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
+func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
+	gd = genHelperDecoder{d: d}
+	dd = genHelperDecDriver{decDriver: d.d}
+	return
+}
+
+type genHelperEncDriver struct {
+	encDriver
+}
+
+func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
+func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
+	encStructFieldKey(x.encDriver, keyType, s)
+}
+func (x genHelperEncDriver) EncodeSymbol(s string) {
+	x.encDriver.EncodeString(cUTF8, s)
+}
+
+type genHelperDecDriver struct {
+	decDriver
+	C checkOverflow
+}
+
+func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
+func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
+	return decStructFieldKey(x.decDriver, keyType, buf)
+}
+func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
+	return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
+}
+func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
+	return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
+}
+func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
+	f = x.DecodeFloat64()
+	if chkOverflow32 && chkOvf.Float32(f) {
+		panicv.errorf("float32 overflow: %v", f)
+	}
+	return
+}
+func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
+	f = x.DecodeFloat64()
+	if chkOvf.Float32(f) {
+		panicv.errorf("float32 overflow: %v", f)
+	}
+	return
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperEncoder struct {
+	M must
+	e *Encoder
+	F fastpathT 
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+type genHelperDecoder struct {
+	C checkOverflow
+	d *Decoder
+	F fastpathT 
+}
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
+	return f.e.h
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinary() bool {
+	return f.e.be // f.e.hh.isBinaryEncoding()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) IsJSONHandle() bool {
+	return f.e.js
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncFallback(iv interface{}) {
+	// println(">>>>>>>>> EncFallback")
+	// f.e.encodeI(iv, false, false)
+	f.e.encodeValue(reflect.ValueOf(iv), nil, false)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
+	bs, fnerr := iv.MarshalText()
+	f.e.marshal(bs, fnerr, false, cUTF8)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
+	bs, fnerr := iv.MarshalJSON()
+	f.e.marshal(bs, fnerr, true, cUTF8)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
+	bs, fnerr := iv.MarshalBinary()
+	f.e.marshal(bs, fnerr, false, cRAW)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: builtin no longer supported - so we make this method a no-op, 
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
+// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
+// 	if _, ok := f.e.hh.(*BincHandle); ok {
+// 		return timeTypId
+// 	}
+// }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
+	return i2rtid(v)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
+	return f.e.h.getExt(rtid)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
+	f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) HasExtensions() bool {
+	return len(f.e.h.extHandle) != 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
+	if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
+		f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
+		return true
+	}
+	return false 
+}
+
+// ---------------- DECODER FOLLOWS -----------------
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
+	return f.d.h
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinary() bool {
+     return f.d.be // f.d.hh.isBinaryEncoding()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecScratchBuffer() []byte {
+	return f.d.b[:]
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
+	return &f.d.b
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
+	// println(">>>>>>>>> DecFallback")
+	rv := reflect.ValueOf(iv)
+	if chkPtr {
+		rv = f.d.ensureDecodeable(rv)
+	}
+	f.d.decodeValue(rv, nil, false)
+	// f.d.decodeValueFallback(rv)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
+	return f.d.decSliceHelperStart()
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
+	f.d.structFieldNotFound(index, name)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
+	f.d.arrayCannotExpand(sliceLen, streamLen)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
+	fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
+	// bs := f.dd.DecodeStringAsBytes()
+	// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
+	fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
+	fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
+	if fnerr != nil {
+		panic(fnerr)
+	}
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecRaw() []byte {	return f.d.rawBytes() }
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: builtin no longer supported - so we make this method a no-op, 
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
+// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
+// 	// Note: builtin is no longer supported - so make this a no-op
+// 	if _, ok := f.d.hh.(*BincHandle); ok {
+// 		return timeTypId
+// 	}
+// 	return 0
+// }
+
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) IsJSONHandle() bool {
+	return f.d.js 
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
+	return i2rtid(v)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
+	return f.d.h.getExt(rtid)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
+	f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) HasExtensions() bool {
+	return len(f.d.h.extHandle) != 0
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: No longer used,
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
+	if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
+		f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
+		return true
+	}
+	return false 
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
+	return decInferLen(clen, maxlen, unit)
+}
+// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
+//
+// Deprecated: no longer used, 
+// but leave in-place so that old generated files continue to work without regeneration.
+func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
+
diff --git a/vendor/github.com/ugorji/go/codec/gen.generated.go b/vendor/github.com/ugorji/go/codec/gen.generated.go
new file mode 100644
index 0000000..240ba9f
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen.generated.go
@@ -0,0 +1,164 @@
+// +build codecgen.exec
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+// DO NOT EDIT. THIS FILE IS AUTO-GENERATED FROM gen-dec-(map|array).go.tmpl
+
+const genDecMapTmpl = `
+{{var "v"}} := *{{ .Varname }}
+{{var "l"}} := r.ReadMapStart()
+{{var "bh"}} := z.DecBasicHandle()
+if {{var "v"}} == nil {
+	{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
+	{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
+	*{{ .Varname }} = {{var "v"}}
+}
+var {{var "mk"}} {{ .KTyp }}
+var {{var "mv"}} {{ .Typ }}
+var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
+if {{var "bh"}}.MapValueReset {
+	{{if decElemKindPtr}}{{var "mg"}} = true
+	{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
+	{{else if not decElemKindImmutable}}{{var "mg"}} = true
+	{{end}} }
+if {{var "l"}} != 0 {
+{{var "hl"}} := {{var "l"}} > 0 
+	for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
+	r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
+	{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
+{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
+		{{var "mk"}} = string({{var "bv"}})
+	}{{ end }}{{if decElemKindPtr}}
+	{{var "ms"}} = true{{end}}
+	if {{var "mg"}} {
+		{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] 
+		if {{var "mok"}} {
+			{{var "ms"}} = false
+		} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
+	} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
+	r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
+	{{var "mdn"}} = false
+	{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
+	if {{var "mdn"}} {
+		if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
+	} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
+		{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
+	}
+}
+} // else len==0: TODO: Should we clear map entries?
+r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
+`
+
+const genDecListTmpl = `
+{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
+var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
+if {{var "l"}} == 0 {
+	{{if isSlice }}if {{var "v"}} == nil {
+		{{var "v"}} = []{{ .Typ }}{}
+		{{var "c"}} = true
+	} else if len({{var "v"}}) != 0 {
+		{{var "v"}} = {{var "v"}}[:0]
+		{{var "c"}} = true
+	} {{else if isChan }}if {{var "v"}} == nil {
+		{{var "v"}} = make({{ .CTyp }}, 0)
+		{{var "c"}} = true
+	} {{end}}
+} else {
+	{{var "hl"}} := {{var "l"}} > 0
+	var {{var "rl"}} int
+	_ =  {{var "rl"}}
+	{{if isSlice }} if {{var "hl"}} {
+	if {{var "l"}} > cap({{var "v"}}) {
+		{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+		if {{var "rl"}} <= cap({{var "v"}}) {
+			{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
+		} else {
+			{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
+		}
+		{{var "c"}} = true
+	} else if {{var "l"}} != len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "l"}}]
+		{{var "c"}} = true
+	}
+	} {{end}}
+	var {{var "j"}} int 
+    // var {{var "dn"}} bool 
+	for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
+		{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
+			if {{var "hl"}} {
+				{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
+			} else {
+				{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
+			}
+			{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
+			{{var "c"}} = true 
+		}{{end}}
+		{{var "h"}}.ElemContainerState({{var "j"}})
+        {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
+        {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
+		{{ decLineVar $x }}
+		{{var "v"}} <- {{ $x }}
+        // println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
+        {{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
+		var {{var "db"}} bool
+		if {{var "j"}} >= len({{var "v"}}) {
+			{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
+			{{var "c"}} = true
+			{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
+			{{end}}
+		}
+		if {{var "db"}} {
+			z.DecSwallow()
+		} else {
+			{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
+		}
+        {{end}}
+	}
+	{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
+		{{var "v"}} = {{var "v"}}[:{{var "j"}}]
+		{{var "c"}} = true
+	} else if {{var "j"}} == 0 && {{var "v"}} == nil {
+		{{var "v"}} = make([]{{ .Typ }}, 0)
+		{{var "c"}} = true
+	} {{end}}
+}
+{{var "h"}}.End()
+{{if not isArray }}if {{var "c"}} { 
+	*{{ .Varname }} = {{var "v"}}
+}{{end}}
+`
+
+const genEncChanTmpl = `
+{{.Label}}:
+switch timeout{{.Sfx}} :=  z.EncBasicHandle().ChanRecvTimeout; {
+case timeout{{.Sfx}} == 0: // only consume available
+	for {
+		select {
+		case b{{.Sfx}} := <-{{.Chan}}:
+			{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
+		default:
+			break {{.Label}}
+		}
+	}
+case timeout{{.Sfx}} > 0: // consume until timeout
+	tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
+	for {
+		select {
+		case b{{.Sfx}} := <-{{.Chan}}:
+			{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
+		case <-tt{{.Sfx}}.C:
+			// close(tt.C)
+			break {{.Label}}
+		}
+	}
+default: // consume until close
+	for b{{.Sfx}} := range {{.Chan}} {
+		{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
+	}
+}
+`
diff --git a/vendor/github.com/ugorji/go/codec/gen.go b/vendor/github.com/ugorji/go/codec/gen.go
new file mode 100644
index 0000000..b4c4031
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/gen.go
@@ -0,0 +1,2139 @@
+// +build codecgen.exec
+
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"bytes"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"go/format"
+	"io"
+	"io/ioutil"
+	"math/rand"
+	"reflect"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"text/template"
+	"time"
+	"unicode"
+	"unicode/utf8"
+)
+
+// ---------------------------------------------------
+// codecgen supports the full cycle of reflection-based codec:
+//    - RawExt
+//    - Raw
+//    - Extensions
+//    - (Binary|Text|JSON)(Unm|M)arshal
+//    - generic by-kind
+//
+// This means that, for dynamic things, we MUST use reflection to at least get the reflect.Type.
+// In those areas, we try to only do reflection or interface-conversion when NECESSARY:
+//    - Extensions, only if Extensions are configured.
+//
+// However, codecgen doesn't support the following:
+//   - Canonical option. (codecgen IGNORES it currently)
+//     This is just because it has not been implemented.
+//
+// During encode/decode, Selfer takes precedence.
+// A type implementing Selfer will know how to encode/decode itself statically.
+//
+// The following field types are supported:
+//     array: [n]T
+//     slice: []T
+//     map: map[K]V
+//     primitive: [u]int[n], float(32|64), bool, string
+//     struct
+//
+// ---------------------------------------------------
+// Note that a Selfer cannot call (e|d).(En|De)code on itself,
+// as this will cause a circular reference, as (En|De)code will call Selfer methods.
+// Any type that implements Selfer must implement completely and not fallback to (En|De)code.
+//
+// In addition, code in this file manages the generation of fast-path implementations of
+// encode/decode of slices/maps of primitive keys/values.
+//
+// Users MUST re-generate their implementations whenever the code shape changes.
+// The generated code will panic if it was generated with a version older than the supporting library.
+// ---------------------------------------------------
+//
+// codec framework is very feature rich.
+// When encoding or decoding into an interface, it depends on the runtime type of the interface.
+// The type of the interface may be a named type, an extension, etc.
+// Consequently, we fallback to runtime codec for encoding/decoding interfaces.
+// In addition, we fallback for any value which cannot be guaranteed at runtime.
+// This allows us support ANY value, including any named types, specifically those which
+// do not implement our interfaces (e.g. Selfer).
+//
+// This explains some slowness compared to other code generation codecs (e.g. msgp).
+// This reduction in speed is only seen when your refers to interfaces,
+// e.g. type T struct { A interface{}; B []interface{}; C map[string]interface{} }
+//
+// codecgen will panic if the file was generated with an old version of the library in use.
+//
+// Note:
+//   It was a conscious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil.
+//   This way, there isn't a function call overhead just to see that we should not enter a block of code.
+//
+// Note:
+//   codecgen-generated code depends on the variables defined by fast-path.generated.go.
+//   consequently, you cannot run with tags "codecgen notfastpath".
+
+// GenVersion is the current version of codecgen.
+//
+// NOTE: Increment this value each time codecgen changes fundamentally.
+// Fundamental changes are:
+//   - helper methods change (signature change, new ones added, some removed, etc)
+//   - codecgen command line changes
+//
+// v1: Initial Version
+// v2:
+// v3: Changes for Kubernetes:
+//     changes in signature of some unpublished helper methods and codecgen cmdline arguments.
+// v4: Removed separator support from (en|de)cDriver, and refactored codec(gen)
+// v5: changes to support faster json decoding. Let encoder/decoder maintain state of collections.
+// v6: removed unsafe from gen, and now uses codecgen.exec tag
+// v7:
+// v8: current - we now maintain compatibility with old generated code.
+const genVersion = 8
+
+const (
+	genCodecPkg        = "codec1978"
+	genTempVarPfx      = "yy"
+	genTopLevelVarName = "x"
+
+	// ignore canBeNil parameter, and always set to true.
+	// This is because nil can appear anywhere, so we should always check.
+	genAnythingCanBeNil = true
+
+	// if genUseOneFunctionForDecStructMap, make a single codecDecodeSelferFromMap function;
+	// else make codecDecodeSelferFromMap{LenPrefix,CheckBreak} so that conditionals
+	// are not executed a lot.
+	//
+	// From testing, it didn't make much difference in runtime, so keep as true (one function only)
+	genUseOneFunctionForDecStructMap = true
+)
+
+type genStructMapStyle uint8
+
+const (
+	genStructMapStyleConsolidated genStructMapStyle = iota
+	genStructMapStyleLenPrefix
+	genStructMapStyleCheckBreak
+)
+
+var (
+	errGenAllTypesSamePkg  = errors.New("All types must be in the same package")
+	errGenExpectArrayOrMap = errors.New("unexpected type. Expecting array/map/slice")
+
+	genBase64enc  = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789__")
+	genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
+)
+
+type genBuf struct {
+	buf []byte
+}
+
+func (x *genBuf) s(s string) *genBuf              { x.buf = append(x.buf, s...); return x }
+func (x *genBuf) b(s []byte) *genBuf              { x.buf = append(x.buf, s...); return x }
+func (x *genBuf) v() string                       { return string(x.buf) }
+func (x *genBuf) f(s string, args ...interface{}) { x.s(fmt.Sprintf(s, args...)) }
+func (x *genBuf) reset() {
+	if x.buf != nil {
+		x.buf = x.buf[:0]
+	}
+}
+
+// genRunner holds some state used during a Gen run.
+type genRunner struct {
+	w io.Writer      // output
+	c uint64         // counter used for generating varsfx
+	t []reflect.Type // list of types to run selfer on
+
+	tc reflect.Type     // currently running selfer on this type
+	te map[uintptr]bool // types for which the encoder has been created
+	td map[uintptr]bool // types for which the decoder has been created
+	cp string           // codec import path
+
+	im  map[string]reflect.Type // imports to add
+	imn map[string]string       // package names of imports to add
+	imc uint64                  // counter for import numbers
+
+	is map[reflect.Type]struct{} // types seen during import search
+	bp string                    // base PkgPath, for which we are generating for
+
+	cpfx string // codec package prefix
+
+	tm map[reflect.Type]struct{} // types for which enc/dec must be generated
+	ts []reflect.Type            // types for which enc/dec must be generated
+
+	xs string // top level variable/constant suffix
+	hn string // fn helper type name
+
+	ti *TypeInfos
+	// rr *rand.Rand // random generator for file-specific types
+
+	nx bool // no extensions
+}
+
+// Gen will write a complete go file containing Selfer implementations for each
+// type passed. All the types must be in the same package.
+//
+// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINUOUSLY WITHOUT NOTICE.
+func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
+	ti *TypeInfos, typ ...reflect.Type) {
+	// All types passed to this method do not have a codec.Selfer method implemented directly.
+	// codecgen already checks the AST and skips any types that define the codec.Selfer methods.
+	// Consequently, there's no need to check and trim them if they implement codec.Selfer
+
+	if len(typ) == 0 {
+		return
+	}
+	x := genRunner{
+		w:   w,
+		t:   typ,
+		te:  make(map[uintptr]bool),
+		td:  make(map[uintptr]bool),
+		im:  make(map[string]reflect.Type),
+		imn: make(map[string]string),
+		is:  make(map[reflect.Type]struct{}),
+		tm:  make(map[reflect.Type]struct{}),
+		ts:  []reflect.Type{},
+		bp:  genImportPath(typ[0]),
+		xs:  uid,
+		ti:  ti,
+		nx:  noExtensions,
+	}
+	if x.ti == nil {
+		x.ti = defTypeInfos
+	}
+	if x.xs == "" {
+		rr := rand.New(rand.NewSource(time.Now().UnixNano()))
+		x.xs = strconv.FormatInt(rr.Int63n(9999), 10)
+	}
+
+	// gather imports first:
+	x.cp = genImportPath(reflect.TypeOf(x))
+	x.imn[x.cp] = genCodecPkg
+	for _, t := range typ {
+		// fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name())
+		if genImportPath(t) != x.bp {
+			panic(errGenAllTypesSamePkg)
+		}
+		x.genRefPkgs(t)
+	}
+	if buildTags != "" {
+		x.line("// +build " + buildTags)
+		x.line("")
+	}
+	x.line(`
+
+// Code generated by codecgen - DO NOT EDIT.
+
+`)
+	x.line("package " + pkgName)
+	x.line("")
+	x.line("import (")
+	if x.cp != x.bp {
+		x.cpfx = genCodecPkg + "."
+		x.linef("%s \"%s\"", genCodecPkg, x.cp)
+	}
+	// use a sorted set of im keys, so that we can get consistent output
+	imKeys := make([]string, 0, len(x.im))
+	for k := range x.im {
+		imKeys = append(imKeys, k)
+	}
+	sort.Strings(imKeys)
+	for _, k := range imKeys { // for k, _ := range x.im {
+		if k == x.imn[k] {
+			x.linef("\"%s\"", k)
+		} else {
+			x.linef("%s \"%s\"", x.imn[k], k)
+		}
+	}
+	// add required packages
+	for _, k := range [...]string{"runtime", "errors", "strconv"} { // "reflect", "fmt"
+		if _, ok := x.im[k]; !ok {
+			x.line("\"" + k + "\"")
+		}
+	}
+	x.line(")")
+	x.line("")
+
+	x.line("const (")
+	x.linef("// ----- content types ----")
+	x.linef("codecSelferCcUTF8%s = %v", x.xs, int64(cUTF8))
+	x.linef("codecSelferCcRAW%s = %v", x.xs, int64(cRAW))
+	x.linef("// ----- value types used ----")
+	for _, vt := range [...]valueType{
+		valueTypeArray, valueTypeMap, valueTypeString,
+		valueTypeInt, valueTypeUint, valueTypeFloat} {
+		x.linef("codecSelferValueType%s%s = %v", vt.String(), x.xs, int64(vt))
+	}
+
+	x.linef("codecSelferBitsize%s = uint8(32 << (^uint(0) >> 63))", x.xs)
+	x.line(")")
+	x.line("var (")
+	x.line("errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + " = errors.New(`only encoded map or array can be decoded into a struct`)")
+	x.line(")")
+	x.line("")
+
+	x.hn = "codecSelfer" + x.xs
+	x.line("type " + x.hn + " struct{}")
+	x.line("")
+
+	x.varsfxreset()
+	x.line("func init() {")
+	x.linef("if %sGenVersion != %v {", x.cpfx, genVersion)
+	x.line("_, file, _, _ := runtime.Caller(0)")
+	x.outf(`panic("codecgen version mismatch: current: %v, need " + strconv.FormatInt(int64(%sGenVersion), 10) + ". Re-generate file: " + file)`, genVersion, x.cpfx)
+	// x.out(`panic(fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `)
+	// x.linef(`%v, %sGenVersion, file))`, genVersion, x.cpfx)
+	x.linef("}")
+	x.line("if false { // reference the types, but skip this branch at build/run time")
+	// x.line("_ = strconv.ParseInt")
+	var n int
+	// for k, t := range x.im {
+	for _, k := range imKeys {
+		t := x.im[k]
+		x.linef("var v%v %s.%s", n, x.imn[k], t.Name())
+		n++
+	}
+	if n > 0 {
+		x.out("_")
+		for i := 1; i < n; i++ {
+			x.out(", _")
+		}
+		x.out(" = v0")
+		for i := 1; i < n; i++ {
+			x.outf(", v%v", i)
+		}
+	}
+	x.line("} ") // close if false
+	x.line("}")  // close init
+	x.line("")
+
+	// generate rest of type info
+	for _, t := range typ {
+		x.tc = t
+		x.selfer(true)
+		x.selfer(false)
+	}
+
+	for _, t := range x.ts {
+		rtid := rt2id(t)
+		// generate enc functions for all these slice/map types.
+		x.varsfxreset()
+		x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
+		x.genRequiredMethodVars(true)
+		switch t.Kind() {
+		case reflect.Array, reflect.Slice, reflect.Chan:
+			x.encListFallback("v", t)
+		case reflect.Map:
+			x.encMapFallback("v", t)
+		default:
+			panic(errGenExpectArrayOrMap)
+		}
+		x.line("}")
+		x.line("")
+
+		// generate dec functions for all these slice/map types.
+		x.varsfxreset()
+		x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx)
+		x.genRequiredMethodVars(false)
+		switch t.Kind() {
+		case reflect.Array, reflect.Slice, reflect.Chan:
+			x.decListFallback("v", rtid, t)
+		case reflect.Map:
+			x.decMapFallback("v", rtid, t)
+		default:
+			panic(errGenExpectArrayOrMap)
+		}
+		x.line("}")
+		x.line("")
+	}
+
+	x.line("")
+}
+
+func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool {
+	// return varname != genTopLevelVarName && t != x.tc
+	// the only time we checkForSelfer is if we are not at the TOP of the generated code.
+	return varname != genTopLevelVarName
+}
+
+func (x *genRunner) arr2str(t reflect.Type, s string) string {
+	if t.Kind() == reflect.Array {
+		return s
+	}
+	return ""
+}
+
+func (x *genRunner) genRequiredMethodVars(encode bool) {
+	x.line("var h " + x.hn)
+	if encode {
+		x.line("z, r := " + x.cpfx + "GenHelperEncoder(e)")
+	} else {
+		x.line("z, r := " + x.cpfx + "GenHelperDecoder(d)")
+	}
+	x.line("_, _, _ = h, z, r")
+}
+
+func (x *genRunner) genRefPkgs(t reflect.Type) {
+	if _, ok := x.is[t]; ok {
+		return
+	}
+	x.is[t] = struct{}{}
+	tpkg, tname := genImportPath(t), t.Name()
+	if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' {
+		if _, ok := x.im[tpkg]; !ok {
+			x.im[tpkg] = t
+			if idx := strings.LastIndex(tpkg, "/"); idx < 0 {
+				x.imn[tpkg] = tpkg
+			} else {
+				x.imc++
+				x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
+			}
+		}
+	}
+	switch t.Kind() {
+	case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan:
+		x.genRefPkgs(t.Elem())
+	case reflect.Map:
+		x.genRefPkgs(t.Elem())
+		x.genRefPkgs(t.Key())
+	case reflect.Struct:
+		for i := 0; i < t.NumField(); i++ {
+			if fname := t.Field(i).Name; fname != "" && fname[0] >= 'A' && fname[0] <= 'Z' {
+				x.genRefPkgs(t.Field(i).Type)
+			}
+		}
+	}
+}
+
+func (x *genRunner) varsfx() string {
+	x.c++
+	return strconv.FormatUint(x.c, 10)
+}
+
+func (x *genRunner) varsfxreset() {
+	x.c = 0
+}
+
+func (x *genRunner) out(s string) {
+	_, err := io.WriteString(x.w, s)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func (x *genRunner) outf(s string, params ...interface{}) {
+	_, err := fmt.Fprintf(x.w, s, params...)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func (x *genRunner) line(s string) {
+	x.out(s)
+	if len(s) == 0 || s[len(s)-1] != '\n' {
+		x.out("\n")
+	}
+}
+
+func (x *genRunner) linef(s string, params ...interface{}) {
+	x.outf(s, params...)
+	if len(s) == 0 || s[len(s)-1] != '\n' {
+		x.out("\n")
+	}
+}
+
+func (x *genRunner) genTypeName(t reflect.Type) (n string) {
+	// defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }()
+
+	// if the type has a PkgPath, which doesn't match the current package,
+	// then include it.
+	// We cannot depend on t.String() because it includes current package,
+	// or t.PkgPath because it includes full import path,
+	//
+	var ptrPfx string
+	for t.Kind() == reflect.Ptr {
+		ptrPfx += "*"
+		t = t.Elem()
+	}
+	if tn := t.Name(); tn != "" {
+		return ptrPfx + x.genTypeNamePrim(t)
+	}
+	switch t.Kind() {
+	case reflect.Map:
+		return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem())
+	case reflect.Slice:
+		return ptrPfx + "[]" + x.genTypeName(t.Elem())
+	case reflect.Array:
+		return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem())
+	case reflect.Chan:
+		return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem())
+	default:
+		if t == intfTyp {
+			return ptrPfx + "interface{}"
+		} else {
+			return ptrPfx + x.genTypeNamePrim(t)
+		}
+	}
+}
+
+func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) {
+	if t.Name() == "" {
+		return t.String()
+	} else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) {
+		return t.Name()
+	} else {
+		return x.imn[genImportPath(t)] + "." + t.Name()
+		// return t.String() // best way to get the package name inclusive
+	}
+}
+
+func (x *genRunner) genZeroValueR(t reflect.Type) string {
+	// if t is a named type, w
+	switch t.Kind() {
+	case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func,
+		reflect.Slice, reflect.Map, reflect.Invalid:
+		return "nil"
+	case reflect.Bool:
+		return "false"
+	case reflect.String:
+		return `""`
+	case reflect.Struct, reflect.Array:
+		return x.genTypeName(t) + "{}"
+	default: // all numbers
+		return "0"
+	}
+}
+
+func (x *genRunner) genMethodNameT(t reflect.Type) (s string) {
+	return genMethodNameT(t, x.tc)
+}
+
+func (x *genRunner) selfer(encode bool) {
+	t := x.tc
+	t0 := t
+	// always make decode use a pointer receiver,
+	// and structs/arrays always use a ptr receiver (encode|decode)
+	isptr := !encode || t.Kind() == reflect.Array || (t.Kind() == reflect.Struct && t != timeTyp)
+	x.varsfxreset()
+
+	fnSigPfx := "func (" + genTopLevelVarName + " "
+	if isptr {
+		fnSigPfx += "*"
+	}
+	fnSigPfx += x.genTypeName(t)
+	x.out(fnSigPfx)
+
+	if isptr {
+		t = reflect.PtrTo(t)
+	}
+	if encode {
+		x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {")
+		x.genRequiredMethodVars(true)
+		x.encVar(genTopLevelVarName, t)
+	} else {
+		x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {")
+		x.genRequiredMethodVars(false)
+		// do not use decVar, as there is no need to check TryDecodeAsNil
+		// or way to elegantly handle that, and also setting it to a
+		// non-nil value doesn't affect the pointer passed.
+		// x.decVar(genTopLevelVarName, t, false)
+		x.dec(genTopLevelVarName, t0, true)
+	}
+	x.line("}")
+	x.line("")
+
+	if encode || t0.Kind() != reflect.Struct {
+		return
+	}
+
+	// write is containerMap
+	if genUseOneFunctionForDecStructMap {
+		x.out(fnSigPfx)
+		x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {")
+		x.genRequiredMethodVars(false)
+		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleConsolidated)
+		x.line("}")
+		x.line("")
+	} else {
+		x.out(fnSigPfx)
+		x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {")
+		x.genRequiredMethodVars(false)
+		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleLenPrefix)
+		x.line("}")
+		x.line("")
+
+		x.out(fnSigPfx)
+		x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {")
+		x.genRequiredMethodVars(false)
+		x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0, genStructMapStyleCheckBreak)
+		x.line("}")
+		x.line("")
+	}
+
+	// write containerArray
+	x.out(fnSigPfx)
+	x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {")
+	x.genRequiredMethodVars(false)
+	x.decStructArray(genTopLevelVarName, "l", "return", rt2id(t0), t0)
+	x.line("}")
+	x.line("")
+
+}
+
+// used for chan, array, slice, map
+func (x *genRunner) xtraSM(varname string, t reflect.Type, encode, isptr bool) {
+	var ptrPfx, addrPfx string
+	if isptr {
+		ptrPfx = "*"
+	} else {
+		addrPfx = "&"
+	}
+	if encode {
+		x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), ptrPfx, x.genTypeName(t), varname)
+	} else {
+		x.linef("h.dec%s((*%s)(%s%s), d)", x.genMethodNameT(t), x.genTypeName(t), addrPfx, varname)
+	}
+	x.registerXtraT(t)
+}
+
+func (x *genRunner) registerXtraT(t reflect.Type) {
+	// recursively register the types
+	if _, ok := x.tm[t]; ok {
+		return
+	}
+	var tkey reflect.Type
+	switch t.Kind() {
+	case reflect.Chan, reflect.Slice, reflect.Array:
+	case reflect.Map:
+		tkey = t.Key()
+	default:
+		return
+	}
+	x.tm[t] = struct{}{}
+	x.ts = append(x.ts, t)
+	// check if this refers to any xtra types eg. a slice of array: add the array
+	x.registerXtraT(t.Elem())
+	if tkey != nil {
+		x.registerXtraT(tkey)
+	}
+}
+
+// encVar will encode a variable.
+// The parameter, t, is the reflect.Type of the variable itself
+func (x *genRunner) encVar(varname string, t reflect.Type) {
+	// fmt.Printf(">>>>>> varname: %s, t: %v\n", varname, t)
+	var checkNil bool
+	switch t.Kind() {
+	case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan:
+		checkNil = true
+	}
+	if checkNil {
+		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
+	}
+
+	switch t.Kind() {
+	case reflect.Ptr:
+		telem := t.Elem()
+		tek := telem.Kind()
+		if tek == reflect.Array || (tek == reflect.Struct && telem != timeTyp) {
+			x.enc(varname, genNonPtr(t))
+			break
+		}
+		i := x.varsfx()
+		x.line(genTempVarPfx + i + " := *" + varname)
+		x.enc(genTempVarPfx+i, genNonPtr(t))
+	case reflect.Struct, reflect.Array:
+		if t == timeTyp {
+			x.enc(varname, t)
+			break
+		}
+		i := x.varsfx()
+		x.line(genTempVarPfx + i + " := &" + varname)
+		x.enc(genTempVarPfx+i, t)
+	default:
+		x.enc(varname, t)
+	}
+
+	if checkNil {
+		x.line("}")
+	}
+
+}
+
+// enc will encode a variable (varname) of type t, where t represents T.
+// if t is !time.Time and t is of kind reflect.Struct or reflect.Array, varname is of type *T
+// (to prevent copying),
+// else t is of type T
+func (x *genRunner) enc(varname string, t reflect.Type) {
+	rtid := rt2id(t)
+	ti2 := x.ti.get(rtid, t)
+	// We call CodecEncodeSelf if one of the following are honored:
+	//   - the type already implements Selfer, call that
+	//   - the type has a Selfer implementation just created, use that
+	//   - the type is in the list of the ones we will generate for, but it is not currently being generated
+
+	mi := x.varsfx()
+	// tptr := reflect.PtrTo(t)
+	tk := t.Kind()
+	if x.checkForSelfer(t, varname) {
+		if tk == reflect.Array || (tk == reflect.Struct && rtid != timeTypId) { // varname is of type *T
+			// if tptr.Implements(selferTyp) || t.Implements(selferTyp) {
+			if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
+				x.line(varname + ".CodecEncodeSelf(e)")
+				return
+			}
+		} else { // varname is of type T
+			if ti2.cs { // t.Implements(selferTyp) {
+				x.line(varname + ".CodecEncodeSelf(e)")
+				return
+			} else if ti2.csp { // tptr.Implements(selferTyp) {
+				x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname)
+				x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
+				return
+			}
+		}
+
+		if _, ok := x.te[rtid]; ok {
+			x.line(varname + ".CodecEncodeSelf(e)")
+			return
+		}
+	}
+
+	inlist := false
+	for _, t0 := range x.t {
+		if t == t0 {
+			inlist = true
+			if x.checkForSelfer(t, varname) {
+				x.line(varname + ".CodecEncodeSelf(e)")
+				return
+			}
+			break
+		}
+	}
+
+	var rtidAdded bool
+	if t == x.tc {
+		x.te[rtid] = true
+		rtidAdded = true
+	}
+
+	// check if
+	//   - type is time.Time, RawExt, Raw
+	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
+
+	x.line("if false {")           //start if block
+	defer func() { x.line("}") }() //end if block
+
+	if t == timeTyp {
+		x.linef("} else { r.EncodeTime(%s)", varname)
+		return
+	}
+	if t == rawTyp {
+		x.linef("} else { z.EncRaw(%s)", varname)
+		return
+	}
+	if t == rawExtTyp {
+		x.linef("} else { r.EncodeRawExt(%s, e)", varname)
+		return
+	}
+	// only check for extensions if the type is named, and has a packagePath.
+	var arrayOrStruct = tk == reflect.Array || tk == reflect.Struct // meaning varname if of type *T
+	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
+		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
+		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.EncExtension(%s, %s) ", yy, varname, yy, varname, yy)
+	}
+	if arrayOrStruct { // varname is of type *T
+		if ti2.bm || ti2.bmp { // t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) {
+			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
+		}
+		if ti2.jm || ti2.jmp { // t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
+		} else if ti2.tm || ti2.tmp { // t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
+		}
+	} else { // varname is of type T
+		if ti2.bm { // t.Implements(binaryMarshalerTyp) {
+			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(%v) ", varname)
+		} else if ti2.bmp { // tptr.Implements(binaryMarshalerTyp) {
+			x.linef("} else if z.EncBinary() { z.EncBinaryMarshal(&%v) ", varname)
+		}
+		if ti2.jm { // t.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", varname)
+		} else if ti2.jmp { // tptr.Implements(jsonMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", varname)
+		} else if ti2.tm { // t.Implements(textMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(%v) ", varname)
+		} else if ti2.tmp { // tptr.Implements(textMarshalerTyp) {
+			x.linef("} else if !z.EncBinary() { z.EncTextMarshal(&%v) ", varname)
+		}
+	}
+	x.line("} else {")
+
+	switch t.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		x.line("r.EncodeInt(int64(" + varname + "))")
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		x.line("r.EncodeUint(uint64(" + varname + "))")
+	case reflect.Float32:
+		x.line("r.EncodeFloat32(float32(" + varname + "))")
+	case reflect.Float64:
+		x.line("r.EncodeFloat64(float64(" + varname + "))")
+	case reflect.Bool:
+		x.line("r.EncodeBool(bool(" + varname + "))")
+	case reflect.String:
+		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", string(" + varname + "))")
+	case reflect.Chan:
+		x.xtraSM(varname, t, true, false)
+		// x.encListFallback(varname, rtid, t)
+	case reflect.Array:
+		x.xtraSM(varname, t, true, true)
+	case reflect.Slice:
+		// if nil, call dedicated function
+		// if a []uint8, call dedicated function
+		// if a known fastpath slice, call dedicated function
+		// else write encode function in-line.
+		// - if elements are primitives or Selfers, call dedicated function on each member.
+		// - else call Encoder.encode(XXX) on it.
+		if rtid == uint8SliceTypId {
+			x.line("r.EncodeStringBytes(codecSelferCcRAW" + x.xs + ", []byte(" + varname + "))")
+		} else if fastpathAV.index(rtid) != -1 {
+			g := x.newGenV(t)
+			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
+		} else {
+			x.xtraSM(varname, t, true, false)
+			// x.encListFallback(varname, rtid, t)
+		}
+	case reflect.Map:
+		// if nil, call dedicated function
+		// if a known fastpath map, call dedicated function
+		// else write encode function in-line.
+		// - if elements are primitives or Selfers, call dedicated function on each member.
+		// - else call Encoder.encode(XXX) on it.
+		// x.line("if " + varname + " == nil { \nr.EncodeNil()\n } else { ")
+		if fastpathAV.index(rtid) != -1 {
+			g := x.newGenV(t)
+			x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", e)")
+		} else {
+			x.xtraSM(varname, t, true, false)
+			// x.encMapFallback(varname, rtid, t)
+		}
+	case reflect.Struct:
+		if !inlist {
+			delete(x.te, rtid)
+			x.line("z.EncFallback(" + varname + ")")
+			break
+		}
+		x.encStruct(varname, rtid, t)
+	default:
+		if rtidAdded {
+			delete(x.te, rtid)
+		}
+		x.line("z.EncFallback(" + varname + ")")
+	}
+}
+
+func (x *genRunner) encZero(t reflect.Type) {
+	switch t.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		x.line("r.EncodeInt(0)")
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		x.line("r.EncodeUint(0)")
+	case reflect.Float32:
+		x.line("r.EncodeFloat32(0)")
+	case reflect.Float64:
+		x.line("r.EncodeFloat64(0)")
+	case reflect.Bool:
+		x.line("r.EncodeBool(false)")
+	case reflect.String:
+		x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + `, "")`)
+	default:
+		x.line("r.EncodeNil()")
+	}
+}
+
+func (x *genRunner) encOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
+	// smartly check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
+	// also, for maps/slices/arrays, check if len ! 0 (not if == zero value)
+	varname2 := varname + "." + t2.Name
+	switch t2.Type.Kind() {
+	case reflect.Struct:
+		rtid2 := rt2id(t2.Type)
+		ti2 := x.ti.get(rtid2, t2.Type)
+		// fmt.Printf(">>>> structfield: omitempty: type: %s, field: %s\n", t2.Type.Name(), t2.Name)
+		if ti2.rtid == timeTypId {
+			buf.s("!(").s(varname2).s(".IsZero())")
+			break
+		}
+		if ti2.isFlag(typeInfoFlagIsZeroerPtr) || ti2.isFlag(typeInfoFlagIsZeroer) {
+			buf.s("!(").s(varname2).s(".IsZero())")
+			break
+		}
+		if ti2.isFlag(typeInfoFlagComparable) {
+			buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
+			break
+		}
+		// buf.s("(")
+		buf.s("false")
+		for i, n := 0, t2.Type.NumField(); i < n; i++ {
+			f := t2.Type.Field(i)
+			if f.PkgPath != "" { // unexported
+				continue
+			}
+			buf.s(" || ")
+			x.encOmitEmptyLine(f, varname2, buf)
+		}
+		//buf.s(")")
+	case reflect.Bool:
+		buf.s(varname2)
+	case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan:
+		buf.s("len(").s(varname2).s(") != 0")
+	default:
+		buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
+	}
+}
+
+func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
+	// Use knowledge from structfieldinfo (mbs, encodable fields. Ignore omitempty. )
+	// replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it
+
+	// if t === type currently running selfer on, do for all
+	ti := x.ti.get(rtid, t)
+	i := x.varsfx()
+	sepVarname := genTempVarPfx + "sep" + i
+	numfieldsvar := genTempVarPfx + "q" + i
+	ti2arrayvar := genTempVarPfx + "r" + i
+	struct2arrvar := genTempVarPfx + "2arr" + i
+
+	x.line(sepVarname + " := !z.EncBinary()")
+	x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar)
+	x.linef("_, _ = %s, %s", sepVarname, struct2arrvar)
+	x.linef("const %s bool = %v // struct tag has 'toArray'", ti2arrayvar, ti.toArray)
+
+	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
+
+	// var nn int
+	// due to omitEmpty, we need to calculate the
+	// number of non-empty things we write out first.
+	// This is required as we need to pre-determine the size of the container,
+	// to support length-prefixing.
+	if ti.anyOmitEmpty {
+		x.linef("var %s = [%v]bool{ // should field at this index be written?", numfieldsvar, len(tisfi))
+
+		for j, si := range tisfi {
+			_ = j
+			if !si.omitEmpty() {
+				// x.linef("%s[%v] = true // %s", numfieldsvar, j, si.fieldName)
+				x.linef("true, // %s", si.fieldName)
+				// nn++
+				continue
+			}
+			var t2 reflect.StructField
+			var omitline genBuf
+			{
+				t2typ := t
+				varname3 := varname
+				// go through the loop, record the t2 field explicitly,
+				// and gather the omit line if embedded in pointers.
+				for ij, ix := range si.is {
+					if uint8(ij) == si.nis {
+						break
+					}
+					for t2typ.Kind() == reflect.Ptr {
+						t2typ = t2typ.Elem()
+					}
+					t2 = t2typ.Field(int(ix))
+					t2typ = t2.Type
+					varname3 = varname3 + "." + t2.Name
+					// do not include actual field in the omit line.
+					// that is done subsequently (right after - below).
+					if uint8(ij+1) < si.nis && t2typ.Kind() == reflect.Ptr {
+						omitline.s(varname3).s(" != nil && ")
+					}
+				}
+			}
+			x.encOmitEmptyLine(t2, varname, &omitline)
+			x.linef("%s, // %s", omitline.v(), si.fieldName)
+		}
+		x.line("}")
+		x.linef("_ = %s", numfieldsvar)
+	}
+	// x.linef("var %snn%s int", genTempVarPfx, i)
+	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
+	x.linef("r.WriteArrayStart(%d)", len(tisfi))
+	x.linef("} else {") // if not ti.toArray
+	if ti.anyOmitEmpty {
+		// nn = 0
+		// x.linef("var %snn%s = %v", genTempVarPfx, i, nn)
+		x.linef("var %snn%s int", genTempVarPfx, i)
+		x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
+		x.linef("r.WriteMapStart(%snn%s)", genTempVarPfx, i)
+		x.linef("%snn%s = %v", genTempVarPfx, i, 0)
+	} else {
+		x.linef("r.WriteMapStart(%d)", len(tisfi))
+	}
+	x.line("}") // close if not StructToArray
+
+	for j, si := range tisfi {
+		i := x.varsfx()
+		isNilVarName := genTempVarPfx + "n" + i
+		var labelUsed bool
+		var t2 reflect.StructField
+		{
+			t2typ := t
+			varname3 := varname
+			for ij, ix := range si.is {
+				if uint8(ij) == si.nis {
+					break
+				}
+				for t2typ.Kind() == reflect.Ptr {
+					t2typ = t2typ.Elem()
+				}
+				t2 = t2typ.Field(int(ix))
+				t2typ = t2.Type
+				varname3 = varname3 + "." + t2.Name
+				if t2typ.Kind() == reflect.Ptr {
+					if !labelUsed {
+						x.line("var " + isNilVarName + " bool")
+					}
+					x.line("if " + varname3 + " == nil { " + isNilVarName + " = true ")
+					x.line("goto LABEL" + i)
+					x.line("}")
+					labelUsed = true
+					// "varname3 = new(" + x.genTypeName(t3.Elem()) + ") }")
+				}
+			}
+			// t2 = t.FieldByIndex(si.is)
+		}
+		if labelUsed {
+			x.line("LABEL" + i + ":")
+		}
+		// if the type of the field is a Selfer, or one of the ones
+
+		x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray
+		if labelUsed {
+			x.linef("if %s { r.WriteArrayElem(); r.EncodeNil() } else { ", isNilVarName)
+		}
+		x.line("r.WriteArrayElem()")
+		if si.omitEmpty() {
+			x.linef("if %s[%v] {", numfieldsvar, j)
+		}
+		x.encVar(varname+"."+t2.Name, t2.Type)
+		if si.omitEmpty() {
+			x.linef("} else {")
+			x.encZero(t2.Type)
+			x.linef("}")
+		}
+		if labelUsed {
+			x.line("}")
+		}
+
+		x.linef("} else {") // if not ti.toArray
+
+		if si.omitEmpty() {
+			x.linef("if %s[%v] {", numfieldsvar, j)
+		}
+		x.line("r.WriteMapElemKey()")
+
+		// x.line("r.EncodeString(codecSelferCcUTF8" + x.xs + ", `" + si.encName + "`)")
+		// emulate EncStructFieldKey
+		switch ti.keyType {
+		case valueTypeInt:
+			x.linef("r.EncodeInt(z.M.Int(strconv.ParseInt(`%s`, 10, 64)))", si.encName)
+		case valueTypeUint:
+			x.linef("r.EncodeUint(z.M.Uint(strconv.ParseUint(`%s`, 10, 64)))", si.encName)
+		case valueTypeFloat:
+			x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
+		default: // string
+			x.linef("r.EncodeString(codecSelferCcUTF8%s, `%s`)", x.xs, si.encName)
+		}
+		// x.linef("r.EncStructFieldKey(codecSelferValueType%s%s, `%s`)", ti.keyType.String(), x.xs, si.encName)
+		x.line("r.WriteMapElemValue()")
+		if labelUsed {
+			x.line("if " + isNilVarName + " { r.EncodeNil() } else { ")
+			x.encVar(varname+"."+t2.Name, t2.Type)
+			x.line("}")
+		} else {
+			x.encVar(varname+"."+t2.Name, t2.Type)
+		}
+		if si.omitEmpty() {
+			x.line("}")
+		}
+		x.linef("} ") // end if/else ti.toArray
+	}
+	x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray {
+	x.line("r.WriteArrayEnd()")
+	x.line("} else {")
+	x.line("r.WriteMapEnd()")
+	x.line("}")
+
+}
+
+func (x *genRunner) encListFallback(varname string, t reflect.Type) {
+	elemBytes := t.Elem().Kind() == reflect.Uint8
+	if t.AssignableTo(uint8SliceTyp) {
+		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, varname)
+		return
+	}
+	if t.Kind() == reflect.Array && elemBytes {
+		x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, ((*[%d]byte)(%s))[:])", x.xs, t.Len(), varname)
+		return
+	}
+	i := x.varsfx()
+	if t.Kind() == reflect.Chan {
+		type ts struct {
+			Label, Chan, Slice, Sfx string
+		}
+		tm, err := template.New("").Parse(genEncChanTmpl)
+		if err != nil {
+			panic(err)
+		}
+		x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
+		x.linef("var sch%s []%s", i, x.genTypeName(t.Elem()))
+		err = tm.Execute(x.w, &ts{"Lsch" + i, varname, "sch" + i, i})
+		if err != nil {
+			panic(err)
+		}
+		// x.linef("%s = sch%s", varname, i)
+		if elemBytes {
+			x.linef("r.EncodeStringBytes(codecSelferCcRAW%s, []byte(%s))", x.xs, "sch"+i)
+			x.line("}")
+			return
+		}
+		varname = "sch" + i
+	}
+
+	x.line("r.WriteArrayStart(len(" + varname + "))")
+	x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
+	x.line("r.WriteArrayElem()")
+
+	x.encVar(genTempVarPfx+"v"+i, t.Elem())
+	x.line("}")
+	x.line("r.WriteArrayEnd()")
+	if t.Kind() == reflect.Chan {
+		x.line("}")
+	}
+}
+
+func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
+	// TODO: expand this to handle canonical.
+	i := x.varsfx()
+	x.line("r.WriteMapStart(len(" + varname + "))")
+	x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
+	x.line("r.WriteMapElemKey()")
+	x.encVar(genTempVarPfx+"k"+i, t.Key())
+	x.line("r.WriteMapElemValue()")
+	x.encVar(genTempVarPfx+"v"+i, t.Elem())
+	x.line("}")
+	x.line("r.WriteMapEnd()")
+}
+
+func (x *genRunner) decVarInitPtr(varname, nilvar string, t reflect.Type, si *structFieldInfo,
+	newbuf, nilbuf *genBuf) (t2 reflect.StructField) {
+	//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
+	// t2 = t.FieldByIndex(si.is)
+	t2typ := t
+	varname3 := varname
+	t2kind := t2typ.Kind()
+	var nilbufed bool
+	if si != nil {
+		for ij, ix := range si.is {
+			if uint8(ij) == si.nis {
+				break
+			}
+			for t2typ.Kind() == reflect.Ptr {
+				t2typ = t2typ.Elem()
+			}
+			t2 = t2typ.Field(int(ix))
+			t2typ = t2.Type
+			varname3 = varname3 + "." + t2.Name
+			t2kind = t2typ.Kind()
+			if t2kind != reflect.Ptr {
+				continue
+			}
+			if newbuf != nil {
+				newbuf.f("if %s == nil { %s = new(%s) }\n", varname3, varname3, x.genTypeName(t2typ.Elem()))
+			}
+			if nilbuf != nil {
+				if !nilbufed {
+					nilbuf.s("if true")
+					nilbufed = true
+				}
+				nilbuf.s(" && ").s(varname3).s(" != nil")
+			}
+		}
+	}
+	// if t2typ.Kind() == reflect.Ptr {
+	// 	varname3 = varname3 + t2.Name
+	// }
+	if nilbuf != nil {
+		if nilbufed {
+			nilbuf.s(" { ")
+		}
+		if nilvar != "" {
+			nilbuf.s(nilvar).s(" = true")
+		} else if tk := t2typ.Kind(); tk == reflect.Ptr {
+			if strings.IndexByte(varname3, '.') != -1 || strings.IndexByte(varname3, '[') != -1 {
+				nilbuf.s(varname3).s(" = nil")
+			} else {
+				nilbuf.s("*").s(varname3).s(" = ").s(x.genZeroValueR(t2typ.Elem()))
+			}
+		} else {
+			nilbuf.s(varname3).s(" = ").s(x.genZeroValueR(t2typ))
+		}
+		if nilbufed {
+			nilbuf.s("}")
+		}
+	}
+	return t2
+}
+
+// decVar takes a variable called varname, of type t
+func (x *genRunner) decVarMain(varname, rand string, t reflect.Type, checkNotNil bool) {
+	// We only encode as nil if a nillable value.
+	// This removes some of the wasted checks for TryDecodeAsNil.
+	// We need to think about this more, to see what happens if omitempty, etc
+	// cause a nil value to be stored when something is expected.
+	// This could happen when decoding from a struct encoded as an array.
+	// For that, decVar should be called with canNil=true, to force true as its value.
+	var varname2 string
+	if t.Kind() != reflect.Ptr {
+		if t.PkgPath() != "" || !x.decTryAssignPrimitive(varname, t, false) {
+			x.dec(varname, t, false)
+		}
+	} else {
+		if checkNotNil {
+			x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
+		}
+		// Ensure we set underlying ptr to a non-nil value (so we can deref to it later).
+		// There's a chance of a **T in here which is nil.
+		var ptrPfx string
+		for t = t.Elem(); t.Kind() == reflect.Ptr; t = t.Elem() {
+			ptrPfx += "*"
+			if checkNotNil {
+				x.linef("if %s%s == nil { %s%s = new(%s)}",
+					ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
+			}
+		}
+		// Should we create temp var if a slice/map indexing? No. dec(...) can now handle it.
+
+		if ptrPfx == "" {
+			x.dec(varname, t, true)
+		} else {
+			varname2 = genTempVarPfx + "z" + rand
+			x.line(varname2 + " := " + ptrPfx + varname)
+			x.dec(varname2, t, true)
+		}
+	}
+}
+
+// decVar takes a variable called varname, of type t
+func (x *genRunner) decVar(varname, nilvar string, t reflect.Type, canBeNil, checkNotNil bool) {
+	i := x.varsfx()
+
+	// We only encode as nil if a nillable value.
+	// This removes some of the wasted checks for TryDecodeAsNil.
+	// We need to think about this more, to see what happens if omitempty, etc
+	// cause a nil value to be stored when something is expected.
+	// This could happen when decoding from a struct encoded as an array.
+	// For that, decVar should be called with canNil=true, to force true as its value.
+
+	if !canBeNil {
+		canBeNil = genAnythingCanBeNil || !genIsImmutable(t)
+	}
+
+	if canBeNil {
+		var buf genBuf
+		x.decVarInitPtr(varname, nilvar, t, nil, nil, &buf)
+		x.linef("if r.TryDecodeAsNil() { %s } else {", buf.buf)
+	} else {
+		x.line("// cannot be nil")
+	}
+
+	x.decVarMain(varname, i, t, checkNotNil)
+
+	if canBeNil {
+		x.line("} ")
+	}
+}
+
+// dec will decode a variable (varname) of type t or ptrTo(t) if isptr==true.
+// t is always a basetype (i.e. not of kind reflect.Ptr).
+func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
+	// assumptions:
+	//   - the varname is to a pointer already. No need to take address of it
+	//   - t is always a baseType T (not a *T, etc).
+	rtid := rt2id(t)
+	ti2 := x.ti.get(rtid, t)
+	// tptr := reflect.PtrTo(t)
+	if x.checkForSelfer(t, varname) {
+		if ti2.cs || ti2.csp { // t.Implements(selferTyp) || tptr.Implements(selferTyp) {
+			x.line(varname + ".CodecDecodeSelf(d)")
+			return
+		}
+		if _, ok := x.td[rtid]; ok {
+			x.line(varname + ".CodecDecodeSelf(d)")
+			return
+		}
+	}
+
+	inlist := false
+	for _, t0 := range x.t {
+		if t == t0 {
+			inlist = true
+			if x.checkForSelfer(t, varname) {
+				x.line(varname + ".CodecDecodeSelf(d)")
+				return
+			}
+			break
+		}
+	}
+
+	var rtidAdded bool
+	if t == x.tc {
+		x.td[rtid] = true
+		rtidAdded = true
+	}
+
+	// check if
+	//   - type is time.Time, Raw, RawExt
+	//   - the type implements (Text|JSON|Binary)(Unm|M)arshal
+
+	mi := x.varsfx()
+	// x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi)
+	// x.linef("_ = %sm%s", genTempVarPfx, mi)
+	x.line("if false {")           //start if block
+	defer func() { x.line("}") }() //end if block
+
+	var ptrPfx, addrPfx string
+	if isptr {
+		ptrPfx = "*"
+	} else {
+		addrPfx = "&"
+	}
+	if t == timeTyp {
+		x.linef("} else { %s%v = r.DecodeTime()", ptrPfx, varname)
+		return
+	}
+	if t == rawTyp {
+		x.linef("} else { %s%v = z.DecRaw()", ptrPfx, varname)
+		return
+	}
+
+	if t == rawExtTyp {
+		x.linef("} else { r.DecodeExt(%s%v, 0, nil)", addrPfx, varname)
+		return
+	}
+
+	// only check for extensions if the type is named, and has a packagePath.
+	if !x.nx && genImportPath(t) != "" && t.Name() != "" {
+		// first check if extensions are configued, before doing the interface conversion
+		// x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname)
+		yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
+		x.linef("} else if %s := z.Extension(z.I2Rtid(%s)); %s != nil { z.DecExtension(%s, %s) ", yy, varname, yy, varname, yy)
+	}
+
+	if ti2.bu || ti2.bup { // t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) {
+		x.linef("} else if z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", addrPfx, varname)
+	}
+	if ti2.ju || ti2.jup { // t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) {
+		x.linef("} else if !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", addrPfx, varname)
+	} else if ti2.tu || ti2.tup { // t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) {
+		x.linef("} else if !z.DecBinary() { z.DecTextUnmarshal(%s%v)", addrPfx, varname)
+	}
+
+	x.line("} else {")
+
+	if x.decTryAssignPrimitive(varname, t, isptr) {
+		return
+	}
+
+	switch t.Kind() {
+	case reflect.Array, reflect.Chan:
+		x.xtraSM(varname, t, false, isptr)
+	case reflect.Slice:
+		// if a []uint8, call dedicated function
+		// if a known fastpath slice, call dedicated function
+		// else write encode function in-line.
+		// - if elements are primitives or Selfers, call dedicated function on each member.
+		// - else call Encoder.encode(XXX) on it.
+		if rtid == uint8SliceTypId {
+			x.linef("%s%s = r.DecodeBytes(%s(%s[]byte)(%s), false)",
+				ptrPfx, varname, ptrPfx, ptrPfx, varname)
+		} else if fastpathAV.index(rtid) != -1 {
+			g := x.newGenV(t)
+			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
+		} else {
+			x.xtraSM(varname, t, false, isptr)
+			// x.decListFallback(varname, rtid, false, t)
+		}
+	case reflect.Map:
+		// if a known fastpath map, call dedicated function
+		// else write encode function in-line.
+		// - if elements are primitives or Selfers, call dedicated function on each member.
+		// - else call Encoder.encode(XXX) on it.
+		if fastpathAV.index(rtid) != -1 {
+			g := x.newGenV(t)
+			x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
+		} else {
+			x.xtraSM(varname, t, false, isptr)
+			// x.decMapFallback(varname, rtid, t)
+		}
+	case reflect.Struct:
+		if inlist {
+			// no need to create temp variable if isptr, or x.F or x[F]
+			if isptr || strings.IndexByte(varname, '.') != -1 || strings.IndexByte(varname, '[') != -1 {
+				x.decStruct(varname, rtid, t)
+			} else {
+				varname2 := genTempVarPfx + "j" + mi
+				x.line(varname2 + " := &" + varname)
+				x.decStruct(varname2, rtid, t)
+			}
+		} else {
+			// delete(x.td, rtid)
+			x.line("z.DecFallback(" + addrPfx + varname + ", false)")
+		}
+	default:
+		if rtidAdded {
+			delete(x.te, rtid)
+		}
+		x.line("z.DecFallback(" + addrPfx + varname + ", true)")
+	}
+}
+
+func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type, isptr bool) (done bool) {
+	// This should only be used for exact primitives (ie un-named types).
+	// Named types may be implementations of Selfer, Unmarshaler, etc.
+	// They should be handled by dec(...)
+
+	var ptr string
+	if isptr {
+		ptr = "*"
+	}
+	switch t.Kind() {
+	case reflect.Int:
+		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+	case reflect.Int8:
+		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 8))", ptr, varname, x.genTypeName(t))
+	case reflect.Int16:
+		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 16))", ptr, varname, x.genTypeName(t))
+	case reflect.Int32:
+		x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 32))", ptr, varname, x.genTypeName(t))
+	case reflect.Int64:
+		x.linef("%s%s = (%s)(r.DecodeInt64())", ptr, varname, x.genTypeName(t))
+
+	case reflect.Uint:
+		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+	case reflect.Uint8:
+		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 8))", ptr, varname, x.genTypeName(t))
+	case reflect.Uint16:
+		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 16))", ptr, varname, x.genTypeName(t))
+	case reflect.Uint32:
+		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 32))", ptr, varname, x.genTypeName(t))
+	case reflect.Uint64:
+		x.linef("%s%s = (%s)(r.DecodeUint64())", ptr, varname, x.genTypeName(t))
+	case reflect.Uintptr:
+		x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
+
+	case reflect.Float32:
+		x.linef("%s%s = (%s)(r.DecodeFloat32As64())", ptr, varname, x.genTypeName(t))
+	case reflect.Float64:
+		x.linef("%s%s = (%s)(r.DecodeFloat64())", ptr, varname, x.genTypeName(t))
+
+	case reflect.Bool:
+		x.linef("%s%s = (%s)(r.DecodeBool())", ptr, varname, x.genTypeName(t))
+	case reflect.String:
+		x.linef("%s%s = (%s)(r.DecodeString())", ptr, varname, x.genTypeName(t))
+	default:
+		return false
+	}
+	return true
+}
+
+func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
+	if t.AssignableTo(uint8SliceTyp) {
+		x.line("*" + varname + " = r.DecodeBytes(*((*[]byte)(" + varname + ")), false)")
+		return
+	}
+	if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
+		x.linef("r.DecodeBytes( ((*[%d]byte)(%s))[:], true)", t.Len(), varname)
+		return
+	}
+	type tstruc struct {
+		TempVar   string
+		Rand      string
+		Varname   string
+		CTyp      string
+		Typ       string
+		Immutable bool
+		Size      int
+	}
+	telem := t.Elem()
+	ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())}
+
+	funcs := make(template.FuncMap)
+
+	funcs["decLineVar"] = func(varname string) string {
+		x.decVar(varname, "", telem, false, true)
+		return ""
+	}
+	funcs["var"] = func(s string) string {
+		return ts.TempVar + s + ts.Rand
+	}
+	funcs["zero"] = func() string {
+		return x.genZeroValueR(telem)
+	}
+	funcs["isArray"] = func() bool {
+		return t.Kind() == reflect.Array
+	}
+	funcs["isSlice"] = func() bool {
+		return t.Kind() == reflect.Slice
+	}
+	funcs["isChan"] = func() bool {
+		return t.Kind() == reflect.Chan
+	}
+	tm, err := template.New("").Funcs(funcs).Parse(genDecListTmpl)
+	if err != nil {
+		panic(err)
+	}
+	if err = tm.Execute(x.w, &ts); err != nil {
+		panic(err)
+	}
+}
+
+func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) {
+	type tstruc struct {
+		TempVar string
+		Sfx     string
+		Rand    string
+		Varname string
+		KTyp    string
+		Typ     string
+		Size    int
+	}
+	telem := t.Elem()
+	tkey := t.Key()
+	ts := tstruc{
+		genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(tkey),
+		x.genTypeName(telem), int(telem.Size() + tkey.Size()),
+	}
+
+	funcs := make(template.FuncMap)
+	funcs["decElemZero"] = func() string {
+		return x.genZeroValueR(telem)
+	}
+	funcs["decElemKindImmutable"] = func() bool {
+		return genIsImmutable(telem)
+	}
+	funcs["decElemKindPtr"] = func() bool {
+		return telem.Kind() == reflect.Ptr
+	}
+	funcs["decElemKindIntf"] = func() bool {
+		return telem.Kind() == reflect.Interface
+	}
+	funcs["decLineVarK"] = func(varname string) string {
+		x.decVar(varname, "", tkey, false, true)
+		return ""
+	}
+	funcs["decLineVar"] = func(varname, decodedNilVarname string) string {
+		x.decVar(varname, decodedNilVarname, telem, false, true)
+		return ""
+	}
+	funcs["var"] = func(s string) string {
+		return ts.TempVar + s + ts.Rand
+	}
+
+	tm, err := template.New("").Funcs(funcs).Parse(genDecMapTmpl)
+	if err != nil {
+		panic(err)
+	}
+	if err = tm.Execute(x.w, &ts); err != nil {
+		panic(err)
+	}
+}
+
+func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) {
+	ti := x.ti.get(rtid, t)
+	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
+	x.line("switch (" + kName + ") {")
+	var newbuf, nilbuf genBuf
+	for _, si := range tisfi {
+		x.line("case \"" + si.encName + "\":")
+		newbuf.reset()
+		nilbuf.reset()
+		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
+		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
+		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
+		x.line("}")
+	}
+	x.line("default:")
+	// pass the slice here, so that the string will not escape, and maybe save allocation
+	x.line("z.DecStructFieldNotFound(-1, " + kName + ")")
+	x.line("} // end switch " + kName)
+}
+
+func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style genStructMapStyle) {
+	tpfx := genTempVarPfx
+	ti := x.ti.get(rtid, t)
+	i := x.varsfx()
+	kName := tpfx + "s" + i
+
+	switch style {
+	case genStructMapStyleLenPrefix:
+		x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i)
+	case genStructMapStyleCheckBreak:
+		x.linef("for %sj%s := 0; !r.CheckBreak(); %sj%s++ {", tpfx, i, tpfx, i)
+	default: // 0, otherwise.
+		x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
+		x.linef("for %sj%s := 0; ; %sj%s++ {", tpfx, i, tpfx, i)
+		x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname)
+		x.line("} else { if r.CheckBreak() { break }; }")
+	}
+	x.line("r.ReadMapElemKey()")
+
+	// emulate decstructfieldkey
+	switch ti.keyType {
+	case valueTypeInt:
+		x.linef("%s := z.StringView(strconv.AppendInt(z.DecScratchArrayBuffer()[:0], r.DecodeInt64(), 10))", kName)
+	case valueTypeUint:
+		x.linef("%s := z.StringView(strconv.AppendUint(z.DecScratchArrayBuffer()[:0], r.DecodeUint64(), 10))", kName)
+	case valueTypeFloat:
+		x.linef("%s := z.StringView(strconv.AppendFloat(z.DecScratchArrayBuffer()[:0], r.DecodeFloat64(), 'f', -1, 64))", kName)
+	default: // string
+		x.linef("%s := z.StringView(r.DecodeStringAsBytes())", kName)
+	}
+	// x.linef("%s := z.StringView(r.DecStructFieldKey(codecSelferValueType%s%s, z.DecScratchArrayBuffer()))", kName, ti.keyType.String(), x.xs)
+
+	x.line("r.ReadMapElemValue()")
+	x.decStructMapSwitch(kName, varname, rtid, t)
+
+	x.line("} // end for " + tpfx + "j" + i)
+	x.line("r.ReadMapEnd()")
+}
+
+func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) {
+	tpfx := genTempVarPfx
+	i := x.varsfx()
+	ti := x.ti.get(rtid, t)
+	tisfi := ti.sfiSrc // always use sequence from file. decStruct expects same thing.
+	x.linef("var %sj%s int", tpfx, i)
+	x.linef("var %sb%s bool", tpfx, i)                        // break
+	x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
+	var newbuf, nilbuf genBuf
+	for _, si := range tisfi {
+		x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }",
+			tpfx, i, tpfx, i, tpfx, i,
+			tpfx, i, lenvarname, tpfx, i)
+		x.linef("if %sb%s { r.ReadArrayEnd(); %s }", tpfx, i, breakString)
+		x.line("r.ReadArrayElem()")
+		newbuf.reset()
+		nilbuf.reset()
+		t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
+		x.linef("if r.TryDecodeAsNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
+		x.decVarMain(varname+"."+t2.Name, x.varsfx(), t2.Type, false)
+		x.line("}")
+	}
+	// read remaining values and throw away.
+	x.line("for {")
+	x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }",
+		tpfx, i, tpfx, i, tpfx, i,
+		tpfx, i, lenvarname, tpfx, i)
+	x.linef("if %sb%s { break }", tpfx, i)
+	x.line("r.ReadArrayElem()")
+	x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i)
+	x.line("}")
+	x.line("r.ReadArrayEnd()")
+}
+
+func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
+	// varname MUST be a ptr, or a struct field or a slice element.
+	i := x.varsfx()
+	x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i)
+	x.linef("if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs)
+	x.line(genTempVarPfx + "l" + i + " := r.ReadMapStart()")
+	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
+	x.line("r.ReadMapEnd()")
+	if genUseOneFunctionForDecStructMap {
+		x.line("} else { ")
+		x.linef("%s.codecDecodeSelfFromMap(%sl%s, d)", varname, genTempVarPfx, i)
+	} else {
+		x.line("} else if " + genTempVarPfx + "l" + i + " > 0 { ")
+		x.line(varname + ".codecDecodeSelfFromMapLenPrefix(" + genTempVarPfx + "l" + i + ", d)")
+		x.line("} else {")
+		x.line(varname + ".codecDecodeSelfFromMapCheckBreak(" + genTempVarPfx + "l" + i + ", d)")
+	}
+	x.line("}")
+
+	// else if container is array
+	x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs)
+	x.line(genTempVarPfx + "l" + i + " := r.ReadArrayStart()")
+	x.linef("if %sl%s == 0 {", genTempVarPfx, i)
+	x.line("r.ReadArrayEnd()")
+	x.line("} else { ")
+	x.linef("%s.codecDecodeSelfFromArray(%sl%s, d)", varname, genTempVarPfx, i)
+	x.line("}")
+	// else panic
+	x.line("} else { ")
+	x.line("panic(errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + ")")
+	x.line("} ")
+}
+
+// --------
+
+type genV struct {
+	// genV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice
+	MapKey    string
+	Elem      string
+	Primitive string
+	Size      int
+}
+
+func (x *genRunner) newGenV(t reflect.Type) (v genV) {
+	switch t.Kind() {
+	case reflect.Slice, reflect.Array:
+		te := t.Elem()
+		v.Elem = x.genTypeName(te)
+		v.Size = int(te.Size())
+	case reflect.Map:
+		te, tk := t.Elem(), t.Key()
+		v.Elem = x.genTypeName(te)
+		v.MapKey = x.genTypeName(tk)
+		v.Size = int(te.Size() + tk.Size())
+	default:
+		panic("unexpected type for newGenV. Requires map or slice type")
+	}
+	return
+}
+
+func (x *genV) MethodNamePfx(prefix string, prim bool) string {
+	var name []byte
+	if prefix != "" {
+		name = append(name, prefix...)
+	}
+	if prim {
+		name = append(name, genTitleCaseName(x.Primitive)...)
+	} else {
+		if x.MapKey == "" {
+			name = append(name, "Slice"...)
+		} else {
+			name = append(name, "Map"...)
+			name = append(name, genTitleCaseName(x.MapKey)...)
+		}
+		name = append(name, genTitleCaseName(x.Elem)...)
+	}
+	return string(name)
+
+}
+
+// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise.
+//
+// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled,
+// where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped.
+// We strip it here.
+func genImportPath(t reflect.Type) (s string) {
+	s = t.PkgPath()
+	if genCheckVendor {
+		// HACK: always handle vendoring. It should be typically on in go 1.6, 1.7
+		s = genStripVendor(s)
+	}
+	return
+}
+
+// A go identifier is (letter|_)[letter|number|_]*
+func genGoIdentifier(s string, checkFirstChar bool) string {
+	b := make([]byte, 0, len(s))
+	t := make([]byte, 4)
+	var n int
+	for i, r := range s {
+		if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
+			b = append(b, '_')
+		}
+		// r must be unicode_letter, unicode_digit or _
+		if unicode.IsLetter(r) || unicode.IsDigit(r) {
+			n = utf8.EncodeRune(t, r)
+			b = append(b, t[:n]...)
+		} else {
+			b = append(b, '_')
+		}
+	}
+	return string(b)
+}
+
+func genNonPtr(t reflect.Type) reflect.Type {
+	for t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	return t
+}
+
+func genTitleCaseName(s string) string {
+	switch s {
+	case "interface{}", "interface {}":
+		return "Intf"
+	default:
+		return strings.ToUpper(s[0:1]) + s[1:]
+	}
+}
+
+func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
+	var ptrPfx string
+	for t.Kind() == reflect.Ptr {
+		ptrPfx += "Ptrto"
+		t = t.Elem()
+	}
+	tstr := t.String()
+	if tn := t.Name(); tn != "" {
+		if tRef != nil && genImportPath(t) == genImportPath(tRef) {
+			return ptrPfx + tn
+		} else {
+			if genQNameRegex.MatchString(tstr) {
+				return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
+			} else {
+				return ptrPfx + genCustomTypeName(tstr)
+			}
+		}
+	}
+	switch t.Kind() {
+	case reflect.Map:
+		return ptrPfx + "Map" + genMethodNameT(t.Key(), tRef) + genMethodNameT(t.Elem(), tRef)
+	case reflect.Slice:
+		return ptrPfx + "Slice" + genMethodNameT(t.Elem(), tRef)
+	case reflect.Array:
+		return ptrPfx + "Array" + strconv.FormatInt(int64(t.Len()), 10) + genMethodNameT(t.Elem(), tRef)
+	case reflect.Chan:
+		var cx string
+		switch t.ChanDir() {
+		case reflect.SendDir:
+			cx = "ChanSend"
+		case reflect.RecvDir:
+			cx = "ChanRecv"
+		default:
+			cx = "Chan"
+		}
+		return ptrPfx + cx + genMethodNameT(t.Elem(), tRef)
+	default:
+		if t == intfTyp {
+			return ptrPfx + "Interface"
+		} else {
+			if tRef != nil && genImportPath(t) == genImportPath(tRef) {
+				if t.Name() != "" {
+					return ptrPfx + t.Name()
+				} else {
+					return ptrPfx + genCustomTypeName(tstr)
+				}
+			} else {
+				// best way to get the package name inclusive
+				// return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
+				// return ptrPfx + genBase64enc.EncodeToString([]byte(tstr))
+				if t.Name() != "" && genQNameRegex.MatchString(tstr) {
+					return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
+				} else {
+					return ptrPfx + genCustomTypeName(tstr)
+				}
+			}
+		}
+	}
+}
+
+// genCustomNameForType base64encodes the t.String() value in such a way
+// that it can be used within a function name.
+func genCustomTypeName(tstr string) string {
+	len2 := genBase64enc.EncodedLen(len(tstr))
+	bufx := make([]byte, len2)
+	genBase64enc.Encode(bufx, []byte(tstr))
+	for i := len2 - 1; i >= 0; i-- {
+		if bufx[i] == '=' {
+			len2--
+		} else {
+			break
+		}
+	}
+	return string(bufx[:len2])
+}
+
+func genIsImmutable(t reflect.Type) (v bool) {
+	return isImmutableKind(t.Kind())
+}
+
+type genInternal struct {
+	Version int
+	Values  []genV
+}
+
+func (x genInternal) FastpathLen() (l int) {
+	for _, v := range x.Values {
+		if v.Primitive == "" && !(v.MapKey == "" && v.Elem == "uint8") {
+			l++
+		}
+	}
+	return
+}
+
+func genInternalZeroValue(s string) string {
+	switch s {
+	case "interface{}", "interface {}":
+		return "nil"
+	case "bool":
+		return "false"
+	case "string":
+		return `""`
+	default:
+		return "0"
+	}
+}
+
+var genInternalNonZeroValueIdx [5]uint64
+var genInternalNonZeroValueStrs = [2][5]string{
+	{`"string-is-an-interface"`, "true", `"some-string"`, "11.1", "33"},
+	{`"string-is-an-interface-2"`, "true", `"some-string-2"`, "22.2", "44"},
+}
+
+func genInternalNonZeroValue(s string) string {
+	switch s {
+	case "interface{}", "interface {}":
+		genInternalNonZeroValueIdx[0]++
+		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[0]%2][0] // return string, to remove ambiguity
+	case "bool":
+		genInternalNonZeroValueIdx[1]++
+		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[1]%2][1]
+	case "string":
+		genInternalNonZeroValueIdx[2]++
+		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[2]%2][2]
+	case "float32", "float64", "float", "double":
+		genInternalNonZeroValueIdx[3]++
+		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[3]%2][3]
+	default:
+		genInternalNonZeroValueIdx[4]++
+		return genInternalNonZeroValueStrs[genInternalNonZeroValueIdx[4]%2][4]
+	}
+}
+
+func genInternalEncCommandAsString(s string, vname string) string {
+	switch s {
+	case "uint", "uint8", "uint16", "uint32", "uint64":
+		return "ee.EncodeUint(uint64(" + vname + "))"
+	case "int", "int8", "int16", "int32", "int64":
+		return "ee.EncodeInt(int64(" + vname + "))"
+	case "string":
+		return "ee.EncodeString(cUTF8, " + vname + ")"
+	case "float32":
+		return "ee.EncodeFloat32(" + vname + ")"
+	case "float64":
+		return "ee.EncodeFloat64(" + vname + ")"
+	case "bool":
+		return "ee.EncodeBool(" + vname + ")"
+	// case "symbol":
+	// 	return "ee.EncodeSymbol(" + vname + ")"
+	default:
+		return "e.encode(" + vname + ")"
+	}
+}
+
+func genInternalDecCommandAsString(s string) string {
+	switch s {
+	case "uint":
+		return "uint(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
+	case "uint8":
+		return "uint8(chkOvf.UintV(dd.DecodeUint64(), 8))"
+	case "uint16":
+		return "uint16(chkOvf.UintV(dd.DecodeUint64(), 16))"
+	case "uint32":
+		return "uint32(chkOvf.UintV(dd.DecodeUint64(), 32))"
+	case "uint64":
+		return "dd.DecodeUint64()"
+	case "uintptr":
+		return "uintptr(chkOvf.UintV(dd.DecodeUint64(), uintBitsize))"
+	case "int":
+		return "int(chkOvf.IntV(dd.DecodeInt64(), intBitsize))"
+	case "int8":
+		return "int8(chkOvf.IntV(dd.DecodeInt64(), 8))"
+	case "int16":
+		return "int16(chkOvf.IntV(dd.DecodeInt64(), 16))"
+	case "int32":
+		return "int32(chkOvf.IntV(dd.DecodeInt64(), 32))"
+	case "int64":
+		return "dd.DecodeInt64()"
+
+	case "string":
+		return "dd.DecodeString()"
+	case "float32":
+		return "float32(chkOvf.Float32V(dd.DecodeFloat64()))"
+	case "float64":
+		return "dd.DecodeFloat64()"
+	case "bool":
+		return "dd.DecodeBool()"
+	default:
+		panic(errors.New("gen internal: unknown type for decode: " + s))
+	}
+}
+
+func genInternalSortType(s string, elem bool) string {
+	for _, v := range [...]string{"int", "uint", "float", "bool", "string"} {
+		if strings.HasPrefix(s, v) {
+			if elem {
+				if v == "int" || v == "uint" || v == "float" {
+					return v + "64"
+				} else {
+					return v
+				}
+			}
+			return v + "Slice"
+		}
+	}
+	panic("sorttype: unexpected type: " + s)
+}
+
+func genStripVendor(s string) string {
+	// HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later.
+	// if s contains /vendor/ OR startsWith vendor/, then return everything after it.
+	const vendorStart = "vendor/"
+	const vendorInline = "/vendor/"
+	if i := strings.LastIndex(s, vendorInline); i >= 0 {
+		s = s[i+len(vendorInline):]
+	} else if strings.HasPrefix(s, vendorStart) {
+		s = s[len(vendorStart):]
+	}
+	return s
+}
+
+// var genInternalMu sync.Mutex
+var genInternalV = genInternal{Version: genVersion}
+var genInternalTmplFuncs template.FuncMap
+var genInternalOnce sync.Once
+
+func genInternalInit() {
+	types := [...]string{
+		"interface{}",
+		"string",
+		"float32",
+		"float64",
+		"uint",
+		"uint8",
+		"uint16",
+		"uint32",
+		"uint64",
+		"uintptr",
+		"int",
+		"int8",
+		"int16",
+		"int32",
+		"int64",
+		"bool",
+	}
+	// keep as slice, so it is in specific iteration order.
+	// Initial order was uint64, string, interface{}, int, int64
+	mapvaltypes := [...]string{
+		"interface{}",
+		"string",
+		"uint",
+		"uint8",
+		"uint16",
+		"uint32",
+		"uint64",
+		"uintptr",
+		"int",
+		"int8",
+		"int16",
+		"int32",
+		"int64",
+		"float32",
+		"float64",
+		"bool",
+	}
+	wordSizeBytes := int(intBitsize) / 8
+
+	mapvaltypes2 := map[string]int{
+		"interface{}": 2 * wordSizeBytes,
+		"string":      2 * wordSizeBytes,
+		"uint":        1 * wordSizeBytes,
+		"uint8":       1,
+		"uint16":      2,
+		"uint32":      4,
+		"uint64":      8,
+		"uintptr":     1 * wordSizeBytes,
+		"int":         1 * wordSizeBytes,
+		"int8":        1,
+		"int16":       2,
+		"int32":       4,
+		"int64":       8,
+		"float32":     4,
+		"float64":     8,
+		"bool":        1,
+	}
+	var gt = genInternal{Version: genVersion}
+
+	// For each slice or map type, there must be a (symmetrical) Encode and Decode fast-path function
+	for _, s := range types {
+		gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]})
+		// if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already.
+		// 	gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
+		// }
+		gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]})
+		if _, ok := mapvaltypes2[s]; !ok {
+			gt.Values = append(gt.Values, genV{MapKey: s, Elem: s, Size: 2 * mapvaltypes2[s]})
+		}
+		for _, ms := range mapvaltypes {
+			gt.Values = append(gt.Values, genV{MapKey: s, Elem: ms, Size: mapvaltypes2[s] + mapvaltypes2[ms]})
+		}
+	}
+
+	funcs := make(template.FuncMap)
+	// funcs["haspfx"] = strings.HasPrefix
+	funcs["encmd"] = genInternalEncCommandAsString
+	funcs["decmd"] = genInternalDecCommandAsString
+	funcs["zerocmd"] = genInternalZeroValue
+	funcs["nonzerocmd"] = genInternalNonZeroValue
+	funcs["hasprefix"] = strings.HasPrefix
+	funcs["sorttype"] = genInternalSortType
+
+	genInternalV = gt
+	genInternalTmplFuncs = funcs
+}
+
+// genInternalGoFile is used to generate source files from templates.
+// It is run by the program author alone.
+// Unfortunately, it has to be exported so that it can be called from a command line tool.
+// *** DO NOT USE ***
+func genInternalGoFile(r io.Reader, w io.Writer) (err error) {
+	genInternalOnce.Do(genInternalInit)
+
+	gt := genInternalV
+
+	t := template.New("").Funcs(genInternalTmplFuncs)
+
+	tmplstr, err := ioutil.ReadAll(r)
+	if err != nil {
+		return
+	}
+
+	if t, err = t.Parse(string(tmplstr)); err != nil {
+		return
+	}
+
+	var out bytes.Buffer
+	err = t.Execute(&out, gt)
+	if err != nil {
+		return
+	}
+
+	bout, err := format.Source(out.Bytes())
+	if err != nil {
+		w.Write(out.Bytes()) // write out if error, so we can still see.
+		// w.Write(bout) // write out if error, as much as possible, so we can still see.
+		return
+	}
+	w.Write(bout)
+	return
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
new file mode 100644
index 0000000..9ddbe20
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
@@ -0,0 +1,14 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.5
+
+package codec
+
+import "reflect"
+
+const reflectArrayOfSupported = true
+
+func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
+	return reflect.ArrayOf(count, elem)
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
new file mode 100644
index 0000000..c5fcd66
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
@@ -0,0 +1,14 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.5
+
+package codec
+
+import "reflect"
+
+const reflectArrayOfSupported = false
+
+func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
+	panic("codec: reflect.ArrayOf unsupported in this go version")
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
new file mode 100644
index 0000000..bc39d6b
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
@@ -0,0 +1,15 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.9
+
+package codec
+
+import "reflect"
+
+func makeMapReflect(t reflect.Type, size int) reflect.Value {
+	if size < 0 {
+		return reflect.MakeMapWithSize(t, 4)
+	}
+	return reflect.MakeMapWithSize(t, size)
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go b/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
new file mode 100644
index 0000000..cde4cd3
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
@@ -0,0 +1,12 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.9
+
+package codec
+
+import "reflect"
+
+func makeMapReflect(t reflect.Type, size int) reflect.Value {
+	return reflect.MakeMap(t)
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
new file mode 100644
index 0000000..794133a
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.10
+
+package codec
+
+const allowSetUnexportedEmbeddedPtr = false
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
new file mode 100644
index 0000000..fd92ede
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.10
+
+package codec
+
+const allowSetUnexportedEmbeddedPtr = true
diff --git a/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go b/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
new file mode 100644
index 0000000..8debfa6
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
@@ -0,0 +1,17 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.4
+
+package codec
+
+// This codec package will only work for go1.4 and above.
+// This is for the following reasons:
+//   - go 1.4 was released in 2014
+//   - go runtime is written fully in go
+//   - interface only holds pointers
+//   - reflect.Value is stabilized as 3 words
+
+func init() {
+	panic("codec: go 1.3 and below are not supported")
+}
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
new file mode 100644
index 0000000..0f1bb01
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
@@ -0,0 +1,10 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.5,!go1.6
+
+package codec
+
+import "os"
+
+var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
new file mode 100644
index 0000000..2fb4b05
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
@@ -0,0 +1,10 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.6,!go1.7
+
+package codec
+
+import "os"
+
+var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
new file mode 100644
index 0000000..c5b8155
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build go1.7
+
+package codec
+
+const genCheckVendor = true
diff --git a/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go b/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
new file mode 100644
index 0000000..837cf24
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build !go1.5
+
+package codec
+
+var genCheckVendor = false
diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go
new file mode 100644
index 0000000..bd29895
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/helper.go
@@ -0,0 +1,2414 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+// Contains code shared by both encode and decode.
+
+// Some shared ideas around encoding/decoding
+// ------------------------------------------
+//
+// If an interface{} is passed, we first do a type assertion to see if it is
+// a primitive type or a map/slice of primitive types, and use a fastpath to handle it.
+//
+// If we start with a reflect.Value, we are already in reflect.Value land and
+// will try to grab the function for the underlying Type and directly call that function.
+// This is more performant than calling reflect.Value.Interface().
+//
+// This still helps us bypass many layers of reflection, and give best performance.
+//
+// Containers
+// ------------
+// Containers in the stream are either associative arrays (key-value pairs) or
+// regular arrays (indexed by incrementing integers).
+//
+// Some streams support indefinite-length containers, and use a breaking
+// byte-sequence to denote that the container has come to an end.
+//
+// Some streams also are text-based, and use explicit separators to denote the
+// end/beginning of different values.
+//
+// During encode, we use a high-level condition to determine how to iterate through
+// the container. That decision is based on whether the container is text-based (with
+// separators) or binary (without separators). If binary, we do not even call the
+// encoding of separators.
+//
+// During decode, we use a different high-level condition to determine how to iterate
+// through the containers. That decision is based on whether the stream contained
+// a length prefix, or if it used explicit breaks. If length-prefixed, we assume that
+// it has to be binary, and we do not even try to read separators.
+//
+// Philosophy
+// ------------
+// On decode, this codec will update containers appropriately:
+//    - If struct, update fields from stream into fields of struct.
+//      If field in stream not found in struct, handle appropriately (based on option).
+//      If a struct field has no corresponding value in the stream, leave it AS IS.
+//      If nil in stream, set value to nil/zero value.
+//    - If map, update map from stream.
+//      If the stream value is NIL, set the map to nil.
+//    - if slice, try to update up to length of array in stream.
+//      if container len is less than stream array length,
+//      and container cannot be expanded, handled (based on option).
+//      This means you can decode 4-element stream array into 1-element array.
+//
+// ------------------------------------
+// On encode, user can specify omitEmpty. This means that the value will be omitted
+// if the zero value. The problem may occur during decode, where omitted values do not affect
+// the value being decoded into. This means that if decoding into a struct with an
+// int field with current value=5, and the field is omitted in the stream, then after
+// decoding, the value will still be 5 (not 0).
+// omitEmpty only works if you guarantee that you always decode into zero-values.
+//
+// ------------------------------------
+// We could have truncated a map to remove keys not available in the stream,
+// or set values in the struct which are not in the stream to their zero values.
+// We decided against it because there is no efficient way to do it.
+// We may introduce it as an option later.
+// However, that will require enabling it for both runtime and code generation modes.
+//
+// To support truncate, we need to do 2 passes over the container:
+//   map
+//   - first collect all keys (e.g. in k1)
+//   - for each key in stream, mark k1 that the key should not be removed
+//   - after updating map, do second pass and call delete for all keys in k1 which are not marked
+//   struct:
+//   - for each field, track the *typeInfo s1
+//   - iterate through all s1, and for each one not marked, set value to zero
+//   - this involves checking the possible anonymous fields which are nil ptrs.
+//     too much work.
+//
+// ------------------------------------------
+// Error Handling is done within the library using panic.
+//
+// This way, the code doesn't have to keep checking if an error has happened,
+// and we don't have to keep sending the error value along with each call
+// or storing it in the En|Decoder and checking it constantly along the way.
+//
+// The disadvantage is that small functions which use panics cannot be inlined.
+// The code accounts for that by only using panics behind an interface;
+// since interface calls cannot be inlined, this is irrelevant.
+//
+// We considered storing the error is En|Decoder.
+//   - once it has its err field set, it cannot be used again.
+//   - panicing will be optional, controlled by const flag.
+//   - code should always check error first and return early.
+// We eventually decided against it as it makes the code clumsier to always
+// check for these error conditions.
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	scratchByteArrayLen = 32
+	// initCollectionCap   = 16 // 32 is defensive. 16 is preferred.
+
+	// Support encoding.(Binary|Text)(Unm|M)arshaler.
+	// This constant flag will enable or disable it.
+	supportMarshalInterfaces = true
+
+	// for debugging, set this to false, to catch panic traces.
+	// Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic.
+	recoverPanicToErr = true
+
+	// arrayCacheLen is the length of the cache used in encoder or decoder for
+	// allowing zero-alloc initialization.
+	arrayCacheLen = 8
+
+	// size of the cacheline: defaulting to value for archs: amd64, arm64, 386
+	// should use "runtime/internal/sys".CacheLineSize, but that is not exposed.
+	cacheLineSize = 64
+
+	wordSizeBits = 32 << (^uint(0) >> 63) // strconv.IntSize
+	wordSize     = wordSizeBits / 8
+
+	maxLevelsEmbedding = 15 // use this, so structFieldInfo fits into 8 bytes
+)
+
+var (
+	oneByteArr    = [1]byte{0}
+	zeroByteSlice = oneByteArr[:0:0]
+)
+
+var refBitset bitset32
+var pool pooler
+var panicv panicHdl
+
+func init() {
+	pool.init()
+
+	refBitset.set(byte(reflect.Map))
+	refBitset.set(byte(reflect.Ptr))
+	refBitset.set(byte(reflect.Func))
+	refBitset.set(byte(reflect.Chan))
+}
+
+type charEncoding uint8
+
+const (
+	cRAW charEncoding = iota
+	cUTF8
+	cUTF16LE
+	cUTF16BE
+	cUTF32LE
+	cUTF32BE
+)
+
+// valueType is the stream type
+type valueType uint8
+
+const (
+	valueTypeUnset valueType = iota
+	valueTypeNil
+	valueTypeInt
+	valueTypeUint
+	valueTypeFloat
+	valueTypeBool
+	valueTypeString
+	valueTypeSymbol
+	valueTypeBytes
+	valueTypeMap
+	valueTypeArray
+	valueTypeTime
+	valueTypeExt
+
+	// valueTypeInvalid = 0xff
+)
+
+var valueTypeStrings = [...]string{
+	"Unset",
+	"Nil",
+	"Int",
+	"Uint",
+	"Float",
+	"Bool",
+	"String",
+	"Symbol",
+	"Bytes",
+	"Map",
+	"Array",
+	"Timestamp",
+	"Ext",
+}
+
+func (x valueType) String() string {
+	if int(x) < len(valueTypeStrings) {
+		return valueTypeStrings[x]
+	}
+	return strconv.FormatInt(int64(x), 10)
+}
+
+type seqType uint8
+
+const (
+	_ seqType = iota
+	seqTypeArray
+	seqTypeSlice
+	seqTypeChan
+)
+
+// note that containerMapStart and containerArraySend are not sent.
+// This is because the ReadXXXStart and EncodeXXXStart already does these.
+type containerState uint8
+
+const (
+	_ containerState = iota
+
+	containerMapStart // slot left open, since Driver method already covers it
+	containerMapKey
+	containerMapValue
+	containerMapEnd
+	containerArrayStart // slot left open, since Driver methods already cover it
+	containerArrayElem
+	containerArrayEnd
+)
+
+// // sfiIdx used for tracking where a (field/enc)Name is seen in a []*structFieldInfo
+// type sfiIdx struct {
+// 	name  string
+// 	index int
+// }
+
+// do not recurse if a containing type refers to an embedded type
+// which refers back to its containing type (via a pointer).
+// The second time this back-reference happens, break out,
+// so as not to cause an infinite loop.
+const rgetMaxRecursion = 2
+
+// Anecdotally, we believe most types have <= 12 fields.
+// - even Java's PMD rules set TooManyFields threshold to 15.
+// However, go has embedded fields, which should be regarded as
+// top level, allowing structs to possibly double or triple.
+// In addition, we don't want to keep creating transient arrays,
+// especially for the sfi index tracking, and the evtypes tracking.
+//
+// So - try to keep typeInfoLoadArray within 2K bytes
+const (
+	typeInfoLoadArraySfisLen   = 16
+	typeInfoLoadArraySfiidxLen = 8 * 112
+	typeInfoLoadArrayEtypesLen = 12
+	typeInfoLoadArrayBLen      = 8 * 4
+)
+
+type typeInfoLoad struct {
+	// fNames   []string
+	// encNames []string
+	etypes []uintptr
+	sfis   []structFieldInfo
+}
+
+type typeInfoLoadArray struct {
+	// fNames   [typeInfoLoadArrayLen]string
+	// encNames [typeInfoLoadArrayLen]string
+	sfis   [typeInfoLoadArraySfisLen]structFieldInfo
+	sfiidx [typeInfoLoadArraySfiidxLen]byte
+	etypes [typeInfoLoadArrayEtypesLen]uintptr
+	b      [typeInfoLoadArrayBLen]byte // scratch - used for struct field names
+}
+
+// mirror json.Marshaler and json.Unmarshaler here,
+// so we don't import the encoding/json package
+
+type jsonMarshaler interface {
+	MarshalJSON() ([]byte, error)
+}
+type jsonUnmarshaler interface {
+	UnmarshalJSON([]byte) error
+}
+
+type isZeroer interface {
+	IsZero() bool
+}
+
+// type byteAccepter func(byte) bool
+
+var (
+	bigen               = binary.BigEndian
+	structInfoFieldName = "_struct"
+
+	mapStrIntfTyp  = reflect.TypeOf(map[string]interface{}(nil))
+	mapIntfIntfTyp = reflect.TypeOf(map[interface{}]interface{}(nil))
+	intfSliceTyp   = reflect.TypeOf([]interface{}(nil))
+	intfTyp        = intfSliceTyp.Elem()
+
+	reflectValTyp = reflect.TypeOf((*reflect.Value)(nil)).Elem()
+
+	stringTyp     = reflect.TypeOf("")
+	timeTyp       = reflect.TypeOf(time.Time{})
+	rawExtTyp     = reflect.TypeOf(RawExt{})
+	rawTyp        = reflect.TypeOf(Raw{})
+	uintptrTyp    = reflect.TypeOf(uintptr(0))
+	uint8Typ      = reflect.TypeOf(uint8(0))
+	uint8SliceTyp = reflect.TypeOf([]uint8(nil))
+	uintTyp       = reflect.TypeOf(uint(0))
+	intTyp        = reflect.TypeOf(int(0))
+
+	mapBySliceTyp = reflect.TypeOf((*MapBySlice)(nil)).Elem()
+
+	binaryMarshalerTyp   = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
+	binaryUnmarshalerTyp = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
+
+	textMarshalerTyp   = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+	textUnmarshalerTyp = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+
+	jsonMarshalerTyp   = reflect.TypeOf((*jsonMarshaler)(nil)).Elem()
+	jsonUnmarshalerTyp = reflect.TypeOf((*jsonUnmarshaler)(nil)).Elem()
+
+	selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem()
+	iszeroTyp = reflect.TypeOf((*isZeroer)(nil)).Elem()
+
+	uint8TypId      = rt2id(uint8Typ)
+	uint8SliceTypId = rt2id(uint8SliceTyp)
+	rawExtTypId     = rt2id(rawExtTyp)
+	rawTypId        = rt2id(rawTyp)
+	intfTypId       = rt2id(intfTyp)
+	timeTypId       = rt2id(timeTyp)
+	stringTypId     = rt2id(stringTyp)
+
+	mapStrIntfTypId  = rt2id(mapStrIntfTyp)
+	mapIntfIntfTypId = rt2id(mapIntfIntfTyp)
+	intfSliceTypId   = rt2id(intfSliceTyp)
+	// mapBySliceTypId  = rt2id(mapBySliceTyp)
+
+	intBitsize  = uint8(intTyp.Bits())
+	uintBitsize = uint8(uintTyp.Bits())
+
+	bsAll0x00 = []byte{0, 0, 0, 0, 0, 0, 0, 0}
+	bsAll0xff = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+
+	chkOvf checkOverflow
+
+	errNoFieldNameToStructFieldInfo = errors.New("no field name passed to parseStructFieldInfo")
+)
+
+var defTypeInfos = NewTypeInfos([]string{"codec", "json"})
+
+var immutableKindsSet = [32]bool{
+	// reflect.Invalid:  ,
+	reflect.Bool:       true,
+	reflect.Int:        true,
+	reflect.Int8:       true,
+	reflect.Int16:      true,
+	reflect.Int32:      true,
+	reflect.Int64:      true,
+	reflect.Uint:       true,
+	reflect.Uint8:      true,
+	reflect.Uint16:     true,
+	reflect.Uint32:     true,
+	reflect.Uint64:     true,
+	reflect.Uintptr:    true,
+	reflect.Float32:    true,
+	reflect.Float64:    true,
+	reflect.Complex64:  true,
+	reflect.Complex128: true,
+	// reflect.Array
+	// reflect.Chan
+	// reflect.Func: true,
+	// reflect.Interface
+	// reflect.Map
+	// reflect.Ptr
+	// reflect.Slice
+	reflect.String: true,
+	// reflect.Struct
+	// reflect.UnsafePointer
+}
+
+// Selfer defines methods by which a value can encode or decode itself.
+//
+// Any type which implements Selfer will be able to encode or decode itself.
+// Consequently, during (en|de)code, this takes precedence over
+// (text|binary)(M|Unm)arshal or extension support.
+//
+// Note: *the first set of bytes of any value MUST NOT represent nil in the format*.
+// This is because, during each decode, we first check the the next set of bytes
+// represent nil, and if so, we just set the value to nil.
+type Selfer interface {
+	CodecEncodeSelf(*Encoder)
+	CodecDecodeSelf(*Decoder)
+}
+
+// MapBySlice is a tag interface that denotes wrapped slice should encode as a map in the stream.
+// The slice contains a sequence of key-value pairs.
+// This affords storing a map in a specific sequence in the stream.
+//
+// Example usage:
+//    type T1 []string         // or []int or []Point or any other "slice" type
+//    func (_ T1) MapBySlice{} // T1 now implements MapBySlice, and will be encoded as a map
+//    type T2 struct { KeyValues T1 }
+//
+//    var kvs = []string{"one", "1", "two", "2", "three", "3"}
+//    var v2 = T2{ KeyValues: T1(kvs) }
+//    // v2 will be encoded like the map: {"KeyValues": {"one": "1", "two": "2", "three": "3"} }
+//
+// The support of MapBySlice affords the following:
+//   - A slice type which implements MapBySlice will be encoded as a map
+//   - A slice can be decoded from a map in the stream
+//   - It MUST be a slice type (not a pointer receiver) that implements MapBySlice
+type MapBySlice interface {
+	MapBySlice()
+}
+
+// BasicHandle encapsulates the common options and extension functions.
+//
+// Deprecated: DO NOT USE DIRECTLY. EXPORTED FOR GODOC BENEFIT. WILL BE REMOVED.
+type BasicHandle struct {
+	// BasicHandle is always a part of a different type.
+	// It doesn't have to fit into it own cache lines.
+
+	// TypeInfos is used to get the type info for any type.
+	//
+	// If not configured, the default TypeInfos is used, which uses struct tag keys: codec, json
+	TypeInfos *TypeInfos
+
+	// Note: BasicHandle is not comparable, due to these slices here (extHandle, intf2impls).
+	// If *[]T is used instead, this becomes comparable, at the cost of extra indirection.
+	// Thses slices are used all the time, so keep as slices (not pointers).
+
+	extHandle
+
+	intf2impls
+
+	RPCOptions
+
+	// ---- cache line
+
+	DecodeOptions
+
+	// ---- cache line
+
+	EncodeOptions
+
+	// noBuiltInTypeChecker
+}
+
+func (x *BasicHandle) getBasicHandle() *BasicHandle {
+	return x
+}
+
+func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
+	if x.TypeInfos == nil {
+		return defTypeInfos.get(rtid, rt)
+	}
+	return x.TypeInfos.get(rtid, rt)
+}
+
+// Handle is the interface for a specific encoding format.
+//
+// Typically, a Handle is pre-configured before first time use,
+// and not modified while in use. Such a pre-configured Handle
+// is safe for concurrent access.
+type Handle interface {
+	Name() string
+	getBasicHandle() *BasicHandle
+	recreateEncDriver(encDriver) bool
+	newEncDriver(w *Encoder) encDriver
+	newDecDriver(r *Decoder) decDriver
+	isBinary() bool
+	hasElemSeparators() bool
+	// IsBuiltinType(rtid uintptr) bool
+}
+
+// Raw represents raw formatted bytes.
+// We "blindly" store it during encode and retrieve the raw bytes during decode.
+// Note: it is dangerous during encode, so we may gate the behaviour
+// behind an Encode flag which must be explicitly set.
+type Raw []byte
+
+// RawExt represents raw unprocessed extension data.
+// Some codecs will decode extension data as a *RawExt
+// if there is no registered extension for the tag.
+//
+// Only one of Data or Value is nil.
+// If Data is nil, then the content of the RawExt is in the Value.
+type RawExt struct {
+	Tag uint64
+	// Data is the []byte which represents the raw ext. If nil, ext is exposed in Value.
+	// Data is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of types
+	Data []byte
+	// Value represents the extension, if Data is nil.
+	// Value is used by codecs (e.g. cbor, json) which leverage the format to do
+	// custom serialization of the types.
+	Value interface{}
+}
+
+// BytesExt handles custom (de)serialization of types to/from []byte.
+// It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types.
+type BytesExt interface {
+	// WriteExt converts a value to a []byte.
+	//
+	// Note: v is a pointer iff the registered extension type is a struct or array kind.
+	WriteExt(v interface{}) []byte
+
+	// ReadExt updates a value from a []byte.
+	//
+	// Note: dst is always a pointer kind to the registered extension type.
+	ReadExt(dst interface{}, src []byte)
+}
+
+// InterfaceExt handles custom (de)serialization of types to/from another interface{} value.
+// The Encoder or Decoder will then handle the further (de)serialization of that known type.
+//
+// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of types.
+type InterfaceExt interface {
+	// ConvertExt converts a value into a simpler interface for easy encoding
+	// e.g. convert time.Time to int64.
+	//
+	// Note: v is a pointer iff the registered extension type is a struct or array kind.
+	ConvertExt(v interface{}) interface{}
+
+	// UpdateExt updates a value from a simpler interface for easy decoding
+	// e.g. convert int64 to time.Time.
+	//
+	// Note: dst is always a pointer kind to the registered extension type.
+	UpdateExt(dst interface{}, src interface{})
+}
+
+// Ext handles custom (de)serialization of custom types / extensions.
+type Ext interface {
+	BytesExt
+	InterfaceExt
+}
+
+// addExtWrapper is a wrapper implementation to support former AddExt exported method.
+type addExtWrapper struct {
+	encFn func(reflect.Value) ([]byte, error)
+	decFn func(reflect.Value, []byte) error
+}
+
+func (x addExtWrapper) WriteExt(v interface{}) []byte {
+	bs, err := x.encFn(reflect.ValueOf(v))
+	if err != nil {
+		panic(err)
+	}
+	return bs
+}
+
+func (x addExtWrapper) ReadExt(v interface{}, bs []byte) {
+	if err := x.decFn(reflect.ValueOf(v), bs); err != nil {
+		panic(err)
+	}
+}
+
+func (x addExtWrapper) ConvertExt(v interface{}) interface{} {
+	return x.WriteExt(v)
+}
+
+func (x addExtWrapper) UpdateExt(dest interface{}, v interface{}) {
+	x.ReadExt(dest, v.([]byte))
+}
+
+type extWrapper struct {
+	BytesExt
+	InterfaceExt
+}
+
+type bytesExtFailer struct{}
+
+func (bytesExtFailer) WriteExt(v interface{}) []byte {
+	panicv.errorstr("BytesExt.WriteExt is not supported")
+	return nil
+}
+func (bytesExtFailer) ReadExt(v interface{}, bs []byte) {
+	panicv.errorstr("BytesExt.ReadExt is not supported")
+}
+
+type interfaceExtFailer struct{}
+
+func (interfaceExtFailer) ConvertExt(v interface{}) interface{} {
+	panicv.errorstr("InterfaceExt.ConvertExt is not supported")
+	return nil
+}
+func (interfaceExtFailer) UpdateExt(dest interface{}, v interface{}) {
+	panicv.errorstr("InterfaceExt.UpdateExt is not supported")
+}
+
+type binaryEncodingType struct{}
+
+func (binaryEncodingType) isBinary() bool { return true }
+
+type textEncodingType struct{}
+
+func (textEncodingType) isBinary() bool { return false }
+
+// noBuiltInTypes is embedded into many types which do not support builtins
+// e.g. msgpack, simple, cbor.
+
+// type noBuiltInTypeChecker struct{}
+// func (noBuiltInTypeChecker) IsBuiltinType(rt uintptr) bool { return false }
+// type noBuiltInTypes struct{ noBuiltInTypeChecker }
+
+type noBuiltInTypes struct{}
+
+func (noBuiltInTypes) EncodeBuiltin(rt uintptr, v interface{}) {}
+func (noBuiltInTypes) DecodeBuiltin(rt uintptr, v interface{}) {}
+
+// type noStreamingCodec struct{}
+// func (noStreamingCodec) CheckBreak() bool { return false }
+// func (noStreamingCodec) hasElemSeparators() bool { return false }
+
+type noElemSeparators struct{}
+
+func (noElemSeparators) hasElemSeparators() (v bool)            { return }
+func (noElemSeparators) recreateEncDriver(e encDriver) (v bool) { return }
+
+// bigenHelper.
+// Users must already slice the x completely, because we will not reslice.
+type bigenHelper struct {
+	x []byte // must be correctly sliced to appropriate len. slicing is a cost.
+	w encWriter
+}
+
+func (z bigenHelper) writeUint16(v uint16) {
+	bigen.PutUint16(z.x, v)
+	z.w.writeb(z.x)
+}
+
+func (z bigenHelper) writeUint32(v uint32) {
+	bigen.PutUint32(z.x, v)
+	z.w.writeb(z.x)
+}
+
+func (z bigenHelper) writeUint64(v uint64) {
+	bigen.PutUint64(z.x, v)
+	z.w.writeb(z.x)
+}
+
+type extTypeTagFn struct {
+	rtid    uintptr
+	rtidptr uintptr
+	rt      reflect.Type
+	tag     uint64
+	ext     Ext
+	_       [1]uint64 // padding
+}
+
+type extHandle []extTypeTagFn
+
+// AddExt registes an encode and decode function for a reflect.Type.
+// To deregister an Ext, call AddExt with nil encfn and/or nil decfn.
+//
+// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
+func (o *extHandle) AddExt(rt reflect.Type, tag byte,
+	encfn func(reflect.Value) ([]byte, error),
+	decfn func(reflect.Value, []byte) error) (err error) {
+	if encfn == nil || decfn == nil {
+		return o.SetExt(rt, uint64(tag), nil)
+	}
+	return o.SetExt(rt, uint64(tag), addExtWrapper{encfn, decfn})
+}
+
+// SetExt will set the extension for a tag and reflect.Type.
+// Note that the type must be a named type, and specifically not a pointer or Interface.
+// An error is returned if that is not honored.
+// To Deregister an ext, call SetExt with nil Ext.
+//
+// Deprecated: Use SetBytesExt or SetInterfaceExt on the Handle instead.
+func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) {
+	// o is a pointer, because we may need to initialize it
+	rk := rt.Kind()
+	for rk == reflect.Ptr {
+		rt = rt.Elem()
+		rk = rt.Kind()
+	}
+
+	if rt.PkgPath() == "" || rk == reflect.Interface { // || rk == reflect.Ptr {
+		return fmt.Errorf("codec.Handle.SetExt: Takes named type, not a pointer or interface: %v", rt)
+	}
+
+	rtid := rt2id(rt)
+	switch rtid {
+	case timeTypId, rawTypId, rawExtTypId:
+		// all natively supported type, so cannot have an extension
+		return // TODO: should we silently ignore, or return an error???
+	}
+	// if o == nil {
+	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
+	// }
+	o2 := *o
+	// if o2 == nil {
+	// 	return errors.New("codec.Handle.SetExt: extHandle not initialized")
+	// }
+	for i := range o2 {
+		v := &o2[i]
+		if v.rtid == rtid {
+			v.tag, v.ext = tag, ext
+			return
+		}
+	}
+	rtidptr := rt2id(reflect.PtrTo(rt))
+	*o = append(o2, extTypeTagFn{rtid, rtidptr, rt, tag, ext, [1]uint64{}})
+	return
+}
+
+func (o extHandle) getExt(rtid uintptr) (v *extTypeTagFn) {
+	for i := range o {
+		v = &o[i]
+		if v.rtid == rtid || v.rtidptr == rtid {
+			return
+		}
+	}
+	return nil
+}
+
+func (o extHandle) getExtForTag(tag uint64) (v *extTypeTagFn) {
+	for i := range o {
+		v = &o[i]
+		if v.tag == tag {
+			return
+		}
+	}
+	return nil
+}
+
+type intf2impl struct {
+	rtid uintptr // for intf
+	impl reflect.Type
+	// _    [1]uint64 // padding // not-needed, as *intf2impl is never returned.
+}
+
+type intf2impls []intf2impl
+
+// Intf2Impl maps an interface to an implementing type.
+// This allows us support infering the concrete type
+// and populating it when passed an interface.
+// e.g. var v io.Reader can be decoded as a bytes.Buffer, etc.
+//
+// Passing a nil impl will clear the mapping.
+func (o *intf2impls) Intf2Impl(intf, impl reflect.Type) (err error) {
+	if impl != nil && !impl.Implements(intf) {
+		return fmt.Errorf("Intf2Impl: %v does not implement %v", impl, intf)
+	}
+	rtid := rt2id(intf)
+	o2 := *o
+	for i := range o2 {
+		v := &o2[i]
+		if v.rtid == rtid {
+			v.impl = impl
+			return
+		}
+	}
+	*o = append(o2, intf2impl{rtid, impl})
+	return
+}
+
+func (o intf2impls) intf2impl(rtid uintptr) (rv reflect.Value) {
+	for i := range o {
+		v := &o[i]
+		if v.rtid == rtid {
+			if v.impl == nil {
+				return
+			}
+			if v.impl.Kind() == reflect.Ptr {
+				return reflect.New(v.impl.Elem())
+			}
+			return reflect.New(v.impl).Elem()
+		}
+	}
+	return
+}
+
+type structFieldInfoFlag uint8
+
+const (
+	_ structFieldInfoFlag = 1 << iota
+	structFieldInfoFlagReady
+	structFieldInfoFlagOmitEmpty
+)
+
+func (x *structFieldInfoFlag) flagSet(f structFieldInfoFlag) {
+	*x = *x | f
+}
+
+func (x *structFieldInfoFlag) flagClr(f structFieldInfoFlag) {
+	*x = *x &^ f
+}
+
+func (x structFieldInfoFlag) flagGet(f structFieldInfoFlag) bool {
+	return x&f != 0
+}
+
+func (x structFieldInfoFlag) omitEmpty() bool {
+	return x.flagGet(structFieldInfoFlagOmitEmpty)
+}
+
+func (x structFieldInfoFlag) ready() bool {
+	return x.flagGet(structFieldInfoFlagReady)
+}
+
+type structFieldInfo struct {
+	encName   string // encode name
+	fieldName string // field name
+
+	is  [maxLevelsEmbedding]uint16 // (recursive/embedded) field index in struct
+	nis uint8                      // num levels of embedding. if 1, then it's not embedded.
+	structFieldInfoFlag
+}
+
+func (si *structFieldInfo) setToZeroValue(v reflect.Value) {
+	if v, valid := si.field(v, false); valid {
+		v.Set(reflect.Zero(v.Type()))
+	}
+}
+
+// rv returns the field of the struct.
+// If anonymous, it returns an Invalid
+func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value, valid bool) {
+	// replicate FieldByIndex
+	for i, x := range si.is {
+		if uint8(i) == si.nis {
+			break
+		}
+		if v, valid = baseStructRv(v, update); !valid {
+			return
+		}
+		v = v.Field(int(x))
+	}
+
+	return v, true
+}
+
+// func (si *structFieldInfo) fieldval(v reflect.Value, update bool) reflect.Value {
+// 	v, _ = si.field(v, update)
+// 	return v
+// }
+
+func parseStructInfo(stag string) (toArray, omitEmpty bool, keytype valueType) {
+	keytype = valueTypeString // default
+	if stag == "" {
+		return
+	}
+	for i, s := range strings.Split(stag, ",") {
+		if i == 0 {
+		} else {
+			switch s {
+			case "omitempty":
+				omitEmpty = true
+			case "toarray":
+				toArray = true
+			case "int":
+				keytype = valueTypeInt
+			case "uint":
+				keytype = valueTypeUint
+			case "float":
+				keytype = valueTypeFloat
+				// case "bool":
+				// 	keytype = valueTypeBool
+			case "string":
+				keytype = valueTypeString
+			}
+		}
+	}
+	return
+}
+
+func (si *structFieldInfo) parseTag(stag string) {
+	// if fname == "" {
+	// 	panic(errNoFieldNameToStructFieldInfo)
+	// }
+
+	if stag == "" {
+		return
+	}
+	for i, s := range strings.Split(stag, ",") {
+		if i == 0 {
+			if s != "" {
+				si.encName = s
+			}
+		} else {
+			switch s {
+			case "omitempty":
+				si.flagSet(structFieldInfoFlagOmitEmpty)
+				// si.omitEmpty = true
+				// case "toarray":
+				// 	si.toArray = true
+			}
+		}
+	}
+}
+
+type sfiSortedByEncName []*structFieldInfo
+
+func (p sfiSortedByEncName) Len() int {
+	return len(p)
+}
+
+func (p sfiSortedByEncName) Less(i, j int) bool {
+	return p[i].encName < p[j].encName
+}
+
+func (p sfiSortedByEncName) Swap(i, j int) {
+	p[i], p[j] = p[j], p[i]
+}
+
+const structFieldNodeNumToCache = 4
+
+type structFieldNodeCache struct {
+	rv  [structFieldNodeNumToCache]reflect.Value
+	idx [structFieldNodeNumToCache]uint32
+	num uint8
+}
+
+func (x *structFieldNodeCache) get(key uint32) (fv reflect.Value, valid bool) {
+	for i, k := range &x.idx {
+		if uint8(i) == x.num {
+			return // break
+		}
+		if key == k {
+			return x.rv[i], true
+		}
+	}
+	return
+}
+
+func (x *structFieldNodeCache) tryAdd(fv reflect.Value, key uint32) {
+	if x.num < structFieldNodeNumToCache {
+		x.rv[x.num] = fv
+		x.idx[x.num] = key
+		x.num++
+		return
+	}
+}
+
+type structFieldNode struct {
+	v      reflect.Value
+	cache2 structFieldNodeCache
+	cache3 structFieldNodeCache
+	update bool
+}
+
+func (x *structFieldNode) field(si *structFieldInfo) (fv reflect.Value) {
+	// return si.fieldval(x.v, x.update)
+	// Note: we only cache if nis=2 or nis=3 i.e. up to 2 levels of embedding
+	// This mostly saves us time on the repeated calls to v.Elem, v.Field, etc.
+	var valid bool
+	switch si.nis {
+	case 1:
+		fv = x.v.Field(int(si.is[0]))
+	case 2:
+		if fv, valid = x.cache2.get(uint32(si.is[0])); valid {
+			fv = fv.Field(int(si.is[1]))
+			return
+		}
+		fv = x.v.Field(int(si.is[0]))
+		if fv, valid = baseStructRv(fv, x.update); !valid {
+			return
+		}
+		x.cache2.tryAdd(fv, uint32(si.is[0]))
+		fv = fv.Field(int(si.is[1]))
+	case 3:
+		var key uint32 = uint32(si.is[0])<<16 | uint32(si.is[1])
+		if fv, valid = x.cache3.get(key); valid {
+			fv = fv.Field(int(si.is[2]))
+			return
+		}
+		fv = x.v.Field(int(si.is[0]))
+		if fv, valid = baseStructRv(fv, x.update); !valid {
+			return
+		}
+		fv = fv.Field(int(si.is[1]))
+		if fv, valid = baseStructRv(fv, x.update); !valid {
+			return
+		}
+		x.cache3.tryAdd(fv, key)
+		fv = fv.Field(int(si.is[2]))
+	default:
+		fv, _ = si.field(x.v, x.update)
+	}
+	return
+}
+
+func baseStructRv(v reflect.Value, update bool) (v2 reflect.Value, valid bool) {
+	for v.Kind() == reflect.Ptr {
+		if v.IsNil() {
+			if !update {
+				return
+			}
+			v.Set(reflect.New(v.Type().Elem()))
+		}
+		v = v.Elem()
+	}
+	return v, true
+}
+
+type typeInfoFlag uint8
+
+const (
+	typeInfoFlagComparable = 1 << iota
+	typeInfoFlagIsZeroer
+	typeInfoFlagIsZeroerPtr
+)
+
+// typeInfo keeps information about each (non-ptr) type referenced in the encode/decode sequence.
+//
+// During an encode/decode sequence, we work as below:
+//   - If base is a built in type, en/decode base value
+//   - If base is registered as an extension, en/decode base value
+//   - If type is binary(M/Unm)arshaler, call Binary(M/Unm)arshal method
+//   - If type is text(M/Unm)arshaler, call Text(M/Unm)arshal method
+//   - Else decode appropriately based on the reflect.Kind
+type typeInfo struct {
+	rt      reflect.Type
+	elem    reflect.Type
+	pkgpath string
+
+	rtid uintptr
+	// rv0  reflect.Value // saved zero value, used if immutableKind
+
+	numMeth uint16 // number of methods
+	kind    uint8
+	chandir uint8
+
+	anyOmitEmpty bool      // true if a struct, and any of the fields are tagged "omitempty"
+	toArray      bool      // whether this (struct) type should be encoded as an array
+	keyType      valueType // if struct, how is the field name stored in a stream? default is string
+	mbs          bool      // base type (T or *T) is a MapBySlice
+
+	// ---- cpu cache line boundary?
+	sfiSort []*structFieldInfo // sorted. Used when enc/dec struct to map.
+	sfiSrc  []*structFieldInfo // unsorted. Used when enc/dec struct to array.
+
+	key reflect.Type
+
+	// ---- cpu cache line boundary?
+	// sfis         []structFieldInfo // all sfi, in src order, as created.
+	sfiNamesSort []byte // all names, with indexes into the sfiSort
+
+	// format of marshal type fields below: [btj][mu]p? OR csp?
+
+	bm  bool // T is a binaryMarshaler
+	bmp bool // *T is a binaryMarshaler
+	bu  bool // T is a binaryUnmarshaler
+	bup bool // *T is a binaryUnmarshaler
+	tm  bool // T is a textMarshaler
+	tmp bool // *T is a textMarshaler
+	tu  bool // T is a textUnmarshaler
+	tup bool // *T is a textUnmarshaler
+
+	jm  bool // T is a jsonMarshaler
+	jmp bool // *T is a jsonMarshaler
+	ju  bool // T is a jsonUnmarshaler
+	jup bool // *T is a jsonUnmarshaler
+	cs  bool // T is a Selfer
+	csp bool // *T is a Selfer
+
+	// other flags, with individual bits representing if set.
+	flags typeInfoFlag
+
+	// _ [2]byte   // padding
+	_ [3]uint64 // padding
+}
+
+func (ti *typeInfo) isFlag(f typeInfoFlag) bool {
+	return ti.flags&f != 0
+}
+
+func (ti *typeInfo) indexForEncName(name []byte) (index int16) {
+	var sn []byte
+	if len(name)+2 <= 32 {
+		var buf [32]byte // should not escape
+		sn = buf[:len(name)+2]
+	} else {
+		sn = make([]byte, len(name)+2)
+	}
+	copy(sn[1:], name)
+	sn[0], sn[len(sn)-1] = tiSep2(name), 0xff
+	j := bytes.Index(ti.sfiNamesSort, sn)
+	if j < 0 {
+		return -1
+	}
+	index = int16(uint16(ti.sfiNamesSort[j+len(sn)+1]) | uint16(ti.sfiNamesSort[j+len(sn)])<<8)
+	return
+}
+
+type rtid2ti struct {
+	rtid uintptr
+	ti   *typeInfo
+}
+
+// TypeInfos caches typeInfo for each type on first inspection.
+//
+// It is configured with a set of tag keys, which are used to get
+// configuration for the type.
+type TypeInfos struct {
+	// infos: formerly map[uintptr]*typeInfo, now *[]rtid2ti, 2 words expected
+	infos atomicTypeInfoSlice
+	mu    sync.Mutex
+	tags  []string
+	_     [2]uint64 // padding
+}
+
+// NewTypeInfos creates a TypeInfos given a set of struct tags keys.
+//
+// This allows users customize the struct tag keys which contain configuration
+// of their types.
+func NewTypeInfos(tags []string) *TypeInfos {
+	return &TypeInfos{tags: tags}
+}
+
+func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
+	// check for tags: codec, json, in that order.
+	// this allows seamless support for many configured structs.
+	for _, x := range x.tags {
+		s = t.Get(x)
+		if s != "" {
+			return s
+		}
+	}
+	return
+}
+
+func (x *TypeInfos) find(s []rtid2ti, rtid uintptr) (idx int, ti *typeInfo) {
+	// binary search. adapted from sort/search.go.
+	// if sp == nil {
+	// 	return -1, nil
+	// }
+	// s := *sp
+	h, i, j := 0, 0, len(s)
+	for i < j {
+		h = i + (j-i)/2
+		if s[h].rtid < rtid {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	if i < len(s) && s[i].rtid == rtid {
+		return i, s[i].ti
+	}
+	return i, nil
+}
+
+func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
+	sp := x.infos.load()
+	var idx int
+	if sp != nil {
+		idx, pti = x.find(sp, rtid)
+		if pti != nil {
+			return
+		}
+	}
+
+	rk := rt.Kind()
+
+	if rk == reflect.Ptr { // || (rk == reflect.Interface && rtid != intfTypId) {
+		panicv.errorf("invalid kind passed to TypeInfos.get: %v - %v", rk, rt)
+	}
+
+	// do not hold lock while computing this.
+	// it may lead to duplication, but that's ok.
+	ti := typeInfo{rt: rt, rtid: rtid, kind: uint8(rk), pkgpath: rt.PkgPath()}
+	// ti.rv0 = reflect.Zero(rt)
+
+	// ti.comparable = rt.Comparable()
+	ti.numMeth = uint16(rt.NumMethod())
+
+	ti.bm, ti.bmp = implIntf(rt, binaryMarshalerTyp)
+	ti.bu, ti.bup = implIntf(rt, binaryUnmarshalerTyp)
+	ti.tm, ti.tmp = implIntf(rt, textMarshalerTyp)
+	ti.tu, ti.tup = implIntf(rt, textUnmarshalerTyp)
+	ti.jm, ti.jmp = implIntf(rt, jsonMarshalerTyp)
+	ti.ju, ti.jup = implIntf(rt, jsonUnmarshalerTyp)
+	ti.cs, ti.csp = implIntf(rt, selferTyp)
+
+	b1, b2 := implIntf(rt, iszeroTyp)
+	if b1 {
+		ti.flags |= typeInfoFlagIsZeroer
+	}
+	if b2 {
+		ti.flags |= typeInfoFlagIsZeroerPtr
+	}
+	if rt.Comparable() {
+		ti.flags |= typeInfoFlagComparable
+	}
+
+	switch rk {
+	case reflect.Struct:
+		var omitEmpty bool
+		if f, ok := rt.FieldByName(structInfoFieldName); ok {
+			ti.toArray, omitEmpty, ti.keyType = parseStructInfo(x.structTag(f.Tag))
+		} else {
+			ti.keyType = valueTypeString
+		}
+		pp, pi := pool.tiLoad()
+		pv := pi.(*typeInfoLoadArray)
+		pv.etypes[0] = ti.rtid
+		// vv := typeInfoLoad{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]}
+		vv := typeInfoLoad{pv.etypes[:1], pv.sfis[:0]}
+		x.rget(rt, rtid, omitEmpty, nil, &vv)
+		// ti.sfis = vv.sfis
+		ti.sfiSrc, ti.sfiSort, ti.sfiNamesSort, ti.anyOmitEmpty = rgetResolveSFI(rt, vv.sfis, pv)
+		pp.Put(pi)
+	case reflect.Map:
+		ti.elem = rt.Elem()
+		ti.key = rt.Key()
+	case reflect.Slice:
+		ti.mbs, _ = implIntf(rt, mapBySliceTyp)
+		ti.elem = rt.Elem()
+	case reflect.Chan:
+		ti.elem = rt.Elem()
+		ti.chandir = uint8(rt.ChanDir())
+	case reflect.Array, reflect.Ptr:
+		ti.elem = rt.Elem()
+	}
+	// sfi = sfiSrc
+
+	x.mu.Lock()
+	sp = x.infos.load()
+	if sp == nil {
+		pti = &ti
+		vs := []rtid2ti{{rtid, pti}}
+		x.infos.store(vs)
+	} else {
+		idx, pti = x.find(sp, rtid)
+		if pti == nil {
+			pti = &ti
+			vs := make([]rtid2ti, len(sp)+1)
+			copy(vs, sp[:idx])
+			copy(vs[idx+1:], sp[idx:])
+			vs[idx] = rtid2ti{rtid, pti}
+			x.infos.store(vs)
+		}
+	}
+	x.mu.Unlock()
+	return
+}
+
+func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, omitEmpty bool,
+	indexstack []uint16, pv *typeInfoLoad) {
+	// Read up fields and store how to access the value.
+	//
+	// It uses go's rules for message selectors,
+	// which say that the field with the shallowest depth is selected.
+	//
+	// Note: we consciously use slices, not a map, to simulate a set.
+	//       Typically, types have < 16 fields,
+	//       and iteration using equals is faster than maps there
+	flen := rt.NumField()
+	if flen > (1<<maxLevelsEmbedding - 1) {
+		panicv.errorf("codec: types with > %v fields are not supported - has %v fields",
+			(1<<maxLevelsEmbedding - 1), flen)
+	}
+	// pv.sfis = make([]structFieldInfo, flen)
+LOOP:
+	for j, jlen := uint16(0), uint16(flen); j < jlen; j++ {
+		f := rt.Field(int(j))
+		fkind := f.Type.Kind()
+		// skip if a func type, or is unexported, or structTag value == "-"
+		switch fkind {
+		case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:
+			continue LOOP
+		}
+
+		isUnexported := f.PkgPath != ""
+		if isUnexported && !f.Anonymous {
+			continue
+		}
+		stag := x.structTag(f.Tag)
+		if stag == "-" {
+			continue
+		}
+		var si structFieldInfo
+		var parsed bool
+		// if anonymous and no struct tag (or it's blank),
+		// and a struct (or pointer to struct), inline it.
+		if f.Anonymous && fkind != reflect.Interface {
+			// ^^ redundant but ok: per go spec, an embedded pointer type cannot be to an interface
+			ft := f.Type
+			isPtr := ft.Kind() == reflect.Ptr
+			for ft.Kind() == reflect.Ptr {
+				ft = ft.Elem()
+			}
+			isStruct := ft.Kind() == reflect.Struct
+
+			// Ignore embedded fields of unexported non-struct types.
+			// Also, from go1.10, ignore pointers to unexported struct types
+			// because unmarshal cannot assign a new struct to an unexported field.
+			// See https://golang.org/issue/21357
+			if (isUnexported && !isStruct) || (!allowSetUnexportedEmbeddedPtr && isUnexported && isPtr) {
+				continue
+			}
+			doInline := stag == ""
+			if !doInline {
+				si.parseTag(stag)
+				parsed = true
+				doInline = si.encName == ""
+				// doInline = si.isZero()
+			}
+			if doInline && isStruct {
+				// if etypes contains this, don't call rget again (as fields are already seen here)
+				ftid := rt2id(ft)
+				// We cannot recurse forever, but we need to track other field depths.
+				// So - we break if we see a type twice (not the first time).
+				// This should be sufficient to handle an embedded type that refers to its
+				// owning type, which then refers to its embedded type.
+				processIt := true
+				numk := 0
+				for _, k := range pv.etypes {
+					if k == ftid {
+						numk++
+						if numk == rgetMaxRecursion {
+							processIt = false
+							break
+						}
+					}
+				}
+				if processIt {
+					pv.etypes = append(pv.etypes, ftid)
+					indexstack2 := make([]uint16, len(indexstack)+1)
+					copy(indexstack2, indexstack)
+					indexstack2[len(indexstack)] = j
+					// indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j)
+					x.rget(ft, ftid, omitEmpty, indexstack2, pv)
+				}
+				continue
+			}
+		}
+
+		// after the anonymous dance: if an unexported field, skip
+		if isUnexported {
+			continue
+		}
+
+		if f.Name == "" {
+			panic(errNoFieldNameToStructFieldInfo)
+		}
+
+		// pv.fNames = append(pv.fNames, f.Name)
+		// if si.encName == "" {
+
+		if !parsed {
+			si.encName = f.Name
+			si.parseTag(stag)
+			parsed = true
+		} else if si.encName == "" {
+			si.encName = f.Name
+		}
+		si.fieldName = f.Name
+		si.flagSet(structFieldInfoFlagReady)
+
+		// pv.encNames = append(pv.encNames, si.encName)
+
+		// si.ikind = int(f.Type.Kind())
+		if len(indexstack) > maxLevelsEmbedding-1 {
+			panicv.errorf("codec: only supports up to %v depth of embedding - type has %v depth",
+				maxLevelsEmbedding-1, len(indexstack))
+		}
+		si.nis = uint8(len(indexstack)) + 1
+		copy(si.is[:], indexstack)
+		si.is[len(indexstack)] = j
+
+		if omitEmpty {
+			si.flagSet(structFieldInfoFlagOmitEmpty)
+		}
+		pv.sfis = append(pv.sfis, si)
+	}
+}
+
+func tiSep(name string) uint8 {
+	// (xn[0]%64) // (between 192-255 - outside ascii BMP)
+	// return 0xfe - (name[0] & 63)
+	// return 0xfe - (name[0] & 63) - uint8(len(name))
+	// return 0xfe - (name[0] & 63) - uint8(len(name)&63)
+	// return ((0xfe - (name[0] & 63)) & 0xf8) | (uint8(len(name) & 0x07))
+	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
+}
+
+func tiSep2(name []byte) uint8 {
+	return 0xfe - (name[0] & 63) - uint8(len(name)&63)
+}
+
+// resolves the struct field info got from a call to rget.
+// Returns a trimmed, unsorted and sorted []*structFieldInfo.
+func rgetResolveSFI(rt reflect.Type, x []structFieldInfo, pv *typeInfoLoadArray) (
+	y, z []*structFieldInfo, ss []byte, anyOmitEmpty bool) {
+	sa := pv.sfiidx[:0]
+	sn := pv.b[:]
+	n := len(x)
+
+	var xn string
+	var ui uint16
+	var sep byte
+
+	for i := range x {
+		ui = uint16(i)
+		xn = x[i].encName // fieldName or encName? use encName for now.
+		if len(xn)+2 > cap(pv.b) {
+			sn = make([]byte, len(xn)+2)
+		} else {
+			sn = sn[:len(xn)+2]
+		}
+		// use a custom sep, so that misses are less frequent,
+		// since the sep (first char in search) is as unique as first char in field name.
+		sep = tiSep(xn)
+		sn[0], sn[len(sn)-1] = sep, 0xff
+		copy(sn[1:], xn)
+		j := bytes.Index(sa, sn)
+		if j == -1 {
+			sa = append(sa, sep)
+			sa = append(sa, xn...)
+			sa = append(sa, 0xff, byte(ui>>8), byte(ui))
+		} else {
+			index := uint16(sa[j+len(sn)+1]) | uint16(sa[j+len(sn)])<<8
+			// one of them must be reset to nil,
+			// and the index updated appropriately to the other one
+			if x[i].nis == x[index].nis {
+			} else if x[i].nis < x[index].nis {
+				sa[j+len(sn)], sa[j+len(sn)+1] = byte(ui>>8), byte(ui)
+				if x[index].ready() {
+					x[index].flagClr(structFieldInfoFlagReady)
+					n--
+				}
+			} else {
+				if x[i].ready() {
+					x[i].flagClr(structFieldInfoFlagReady)
+					n--
+				}
+			}
+		}
+
+	}
+	var w []structFieldInfo
+	sharingArray := len(x) <= typeInfoLoadArraySfisLen // sharing array with typeInfoLoadArray
+	if sharingArray {
+		w = make([]structFieldInfo, n)
+	}
+
+	// remove all the nils (non-ready)
+	y = make([]*structFieldInfo, n)
+	n = 0
+	var sslen int
+	for i := range x {
+		if !x[i].ready() {
+			continue
+		}
+		if !anyOmitEmpty && x[i].omitEmpty() {
+			anyOmitEmpty = true
+		}
+		if sharingArray {
+			w[n] = x[i]
+			y[n] = &w[n]
+		} else {
+			y[n] = &x[i]
+		}
+		sslen = sslen + len(x[i].encName) + 4
+		n++
+	}
+	if n != len(y) {
+		panicv.errorf("failure reading struct %v - expecting %d of %d valid fields, got %d",
+			rt, len(y), len(x), n)
+	}
+
+	z = make([]*structFieldInfo, len(y))
+	copy(z, y)
+	sort.Sort(sfiSortedByEncName(z))
+
+	sharingArray = len(sa) <= typeInfoLoadArraySfiidxLen
+	if sharingArray {
+		ss = make([]byte, 0, sslen)
+	} else {
+		ss = sa[:0] // reuse the newly made sa array if necessary
+	}
+	for i := range z {
+		xn = z[i].encName
+		sep = tiSep(xn)
+		ui = uint16(i)
+		ss = append(ss, sep)
+		ss = append(ss, xn...)
+		ss = append(ss, 0xff, byte(ui>>8), byte(ui))
+	}
+	return
+}
+
+func implIntf(rt, iTyp reflect.Type) (base bool, indir bool) {
+	return rt.Implements(iTyp), reflect.PtrTo(rt).Implements(iTyp)
+}
+
+// isEmptyStruct is only called from isEmptyValue, and checks if a struct is empty:
+//    - does it implement IsZero() bool
+//    - is it comparable, and can i compare directly using ==
+//    - if checkStruct, then walk through the encodable fields
+//      and check if they are empty or not.
+func isEmptyStruct(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
+	// v is a struct kind - no need to check again.
+	// We only check isZero on a struct kind, to reduce the amount of times
+	// that we lookup the rtid and typeInfo for each type as we walk the tree.
+
+	vt := v.Type()
+	rtid := rt2id(vt)
+	if tinfos == nil {
+		tinfos = defTypeInfos
+	}
+	ti := tinfos.get(rtid, vt)
+	if ti.rtid == timeTypId {
+		return rv2i(v).(time.Time).IsZero()
+	}
+	if ti.isFlag(typeInfoFlagIsZeroerPtr) && v.CanAddr() {
+		return rv2i(v.Addr()).(isZeroer).IsZero()
+	}
+	if ti.isFlag(typeInfoFlagIsZeroer) {
+		return rv2i(v).(isZeroer).IsZero()
+	}
+	if ti.isFlag(typeInfoFlagComparable) {
+		return rv2i(v) == rv2i(reflect.Zero(vt))
+	}
+	if !checkStruct {
+		return false
+	}
+	// We only care about what we can encode/decode,
+	// so that is what we use to check omitEmpty.
+	for _, si := range ti.sfiSrc {
+		sfv, valid := si.field(v, false)
+		if valid && !isEmptyValue(sfv, tinfos, deref, checkStruct) {
+			return false
+		}
+	}
+	return true
+}
+
+// func roundFloat(x float64) float64 {
+// 	t := math.Trunc(x)
+// 	if math.Abs(x-t) >= 0.5 {
+// 		return t + math.Copysign(1, x)
+// 	}
+// 	return t
+// }
+
+func panicToErr(h errstrDecorator, err *error) {
+	// Note: This method MUST be called directly from defer i.e. defer panicToErr ...
+	// else it seems the recover is not fully handled
+	if recoverPanicToErr {
+		if x := recover(); x != nil {
+			// fmt.Printf("panic'ing with: %v\n", x)
+			// debug.PrintStack()
+			panicValToErr(h, x, err)
+		}
+	}
+}
+
+func panicValToErr(h errstrDecorator, v interface{}, err *error) {
+	switch xerr := v.(type) {
+	case nil:
+	case error:
+		switch xerr {
+		case nil:
+		case io.EOF, io.ErrUnexpectedEOF, errEncoderNotInitialized, errDecoderNotInitialized:
+			// treat as special (bubble up)
+			*err = xerr
+		default:
+			h.wrapErrstr(xerr.Error(), err)
+		}
+	case string:
+		if xerr != "" {
+			h.wrapErrstr(xerr, err)
+		}
+	case fmt.Stringer:
+		if xerr != nil {
+			h.wrapErrstr(xerr.String(), err)
+		}
+	default:
+		h.wrapErrstr(v, err)
+	}
+}
+
+func isImmutableKind(k reflect.Kind) (v bool) {
+	return immutableKindsSet[k]
+}
+
+// ----
+
+type codecFnInfo struct {
+	ti    *typeInfo
+	xfFn  Ext
+	xfTag uint64
+	seq   seqType
+	addrD bool
+	addrF bool // if addrD, this says whether decode function can take a value or a ptr
+	addrE bool
+	ready bool // ready to use
+}
+
+// codecFn encapsulates the captured variables and the encode function.
+// This way, we only do some calculations one times, and pass to the
+// code block that should be called (encapsulated in a function)
+// instead of executing the checks every time.
+type codecFn struct {
+	i  codecFnInfo
+	fe func(*Encoder, *codecFnInfo, reflect.Value)
+	fd func(*Decoder, *codecFnInfo, reflect.Value)
+	_  [1]uint64 // padding
+}
+
+type codecRtidFn struct {
+	rtid uintptr
+	fn   *codecFn
+}
+
+type codecFner struct {
+	// hh Handle
+	h  *BasicHandle
+	s  []codecRtidFn
+	be bool
+	js bool
+	_  [6]byte   // padding
+	_  [3]uint64 // padding
+}
+
+func (c *codecFner) reset(hh Handle) {
+	bh := hh.getBasicHandle()
+	// only reset iff extensions changed or *TypeInfos changed
+	var hhSame = true &&
+		c.h == bh && c.h.TypeInfos == bh.TypeInfos &&
+		len(c.h.extHandle) == len(bh.extHandle) &&
+		(len(c.h.extHandle) == 0 || &c.h.extHandle[0] == &bh.extHandle[0])
+	if !hhSame {
+		// c.hh = hh
+		c.h, bh = bh, c.h // swap both
+		_, c.js = hh.(*JsonHandle)
+		c.be = hh.isBinary()
+		for i := range c.s {
+			c.s[i].fn.i.ready = false
+		}
+	}
+}
+
+func (c *codecFner) get(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *codecFn) {
+	rtid := rt2id(rt)
+
+	for _, x := range c.s {
+		if x.rtid == rtid {
+			// if rtid exists, then there's a *codenFn attached (non-nil)
+			fn = x.fn
+			if fn.i.ready {
+				return
+			}
+			break
+		}
+	}
+	var ti *typeInfo
+	if fn == nil {
+		fn = new(codecFn)
+		if c.s == nil {
+			c.s = make([]codecRtidFn, 0, 8)
+		}
+		c.s = append(c.s, codecRtidFn{rtid, fn})
+	} else {
+		ti = fn.i.ti
+		*fn = codecFn{}
+		fn.i.ti = ti
+		// fn.fe, fn.fd = nil, nil
+	}
+	fi := &(fn.i)
+	fi.ready = true
+	if ti == nil {
+		ti = c.h.getTypeInfo(rtid, rt)
+		fi.ti = ti
+	}
+
+	rk := reflect.Kind(ti.kind)
+
+	if checkCodecSelfer && (ti.cs || ti.csp) {
+		fn.fe = (*Encoder).selferMarshal
+		fn.fd = (*Decoder).selferUnmarshal
+		fi.addrF = true
+		fi.addrD = ti.csp
+		fi.addrE = ti.csp
+	} else if rtid == timeTypId {
+		fn.fe = (*Encoder).kTime
+		fn.fd = (*Decoder).kTime
+	} else if rtid == rawTypId {
+		fn.fe = (*Encoder).raw
+		fn.fd = (*Decoder).raw
+	} else if rtid == rawExtTypId {
+		fn.fe = (*Encoder).rawExt
+		fn.fd = (*Decoder).rawExt
+		fi.addrF = true
+		fi.addrD = true
+		fi.addrE = true
+	} else if xfFn := c.h.getExt(rtid); xfFn != nil {
+		fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext
+		fn.fe = (*Encoder).ext
+		fn.fd = (*Decoder).ext
+		fi.addrF = true
+		fi.addrD = true
+		if rk == reflect.Struct || rk == reflect.Array {
+			fi.addrE = true
+		}
+	} else if supportMarshalInterfaces && c.be && (ti.bm || ti.bmp) && (ti.bu || ti.bup) {
+		fn.fe = (*Encoder).binaryMarshal
+		fn.fd = (*Decoder).binaryUnmarshal
+		fi.addrF = true
+		fi.addrD = ti.bup
+		fi.addrE = ti.bmp
+	} else if supportMarshalInterfaces && !c.be && c.js && (ti.jm || ti.jmp) && (ti.ju || ti.jup) {
+		//If JSON, we should check JSONMarshal before textMarshal
+		fn.fe = (*Encoder).jsonMarshal
+		fn.fd = (*Decoder).jsonUnmarshal
+		fi.addrF = true
+		fi.addrD = ti.jup
+		fi.addrE = ti.jmp
+	} else if supportMarshalInterfaces && !c.be && (ti.tm || ti.tmp) && (ti.tu || ti.tup) {
+		fn.fe = (*Encoder).textMarshal
+		fn.fd = (*Decoder).textUnmarshal
+		fi.addrF = true
+		fi.addrD = ti.tup
+		fi.addrE = ti.tmp
+	} else {
+		if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
+			if ti.pkgpath == "" { // un-named slice or map
+				if idx := fastpathAV.index(rtid); idx != -1 {
+					fn.fe = fastpathAV[idx].encfn
+					fn.fd = fastpathAV[idx].decfn
+					fi.addrD = true
+					fi.addrF = false
+				}
+			} else {
+				// use mapping for underlying type if there
+				var rtu reflect.Type
+				if rk == reflect.Map {
+					rtu = reflect.MapOf(ti.key, ti.elem)
+				} else {
+					rtu = reflect.SliceOf(ti.elem)
+				}
+				rtuid := rt2id(rtu)
+				if idx := fastpathAV.index(rtuid); idx != -1 {
+					xfnf := fastpathAV[idx].encfn
+					xrt := fastpathAV[idx].rt
+					fn.fe = func(e *Encoder, xf *codecFnInfo, xrv reflect.Value) {
+						xfnf(e, xf, xrv.Convert(xrt))
+					}
+					fi.addrD = true
+					fi.addrF = false // meaning it can be an address(ptr) or a value
+					xfnf2 := fastpathAV[idx].decfn
+					fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
+						if xrv.Kind() == reflect.Ptr {
+							xfnf2(d, xf, xrv.Convert(reflect.PtrTo(xrt)))
+						} else {
+							xfnf2(d, xf, xrv.Convert(xrt))
+						}
+					}
+				}
+			}
+		}
+		if fn.fe == nil && fn.fd == nil {
+			switch rk {
+			case reflect.Bool:
+				fn.fe = (*Encoder).kBool
+				fn.fd = (*Decoder).kBool
+			case reflect.String:
+				fn.fe = (*Encoder).kString
+				fn.fd = (*Decoder).kString
+			case reflect.Int:
+				fn.fd = (*Decoder).kInt
+				fn.fe = (*Encoder).kInt
+			case reflect.Int8:
+				fn.fe = (*Encoder).kInt8
+				fn.fd = (*Decoder).kInt8
+			case reflect.Int16:
+				fn.fe = (*Encoder).kInt16
+				fn.fd = (*Decoder).kInt16
+			case reflect.Int32:
+				fn.fe = (*Encoder).kInt32
+				fn.fd = (*Decoder).kInt32
+			case reflect.Int64:
+				fn.fe = (*Encoder).kInt64
+				fn.fd = (*Decoder).kInt64
+			case reflect.Uint:
+				fn.fd = (*Decoder).kUint
+				fn.fe = (*Encoder).kUint
+			case reflect.Uint8:
+				fn.fe = (*Encoder).kUint8
+				fn.fd = (*Decoder).kUint8
+			case reflect.Uint16:
+				fn.fe = (*Encoder).kUint16
+				fn.fd = (*Decoder).kUint16
+			case reflect.Uint32:
+				fn.fe = (*Encoder).kUint32
+				fn.fd = (*Decoder).kUint32
+			case reflect.Uint64:
+				fn.fe = (*Encoder).kUint64
+				fn.fd = (*Decoder).kUint64
+			case reflect.Uintptr:
+				fn.fe = (*Encoder).kUintptr
+				fn.fd = (*Decoder).kUintptr
+			case reflect.Float32:
+				fn.fe = (*Encoder).kFloat32
+				fn.fd = (*Decoder).kFloat32
+			case reflect.Float64:
+				fn.fe = (*Encoder).kFloat64
+				fn.fd = (*Decoder).kFloat64
+			case reflect.Invalid:
+				fn.fe = (*Encoder).kInvalid
+				fn.fd = (*Decoder).kErr
+			case reflect.Chan:
+				fi.seq = seqTypeChan
+				fn.fe = (*Encoder).kSlice
+				fn.fd = (*Decoder).kSlice
+			case reflect.Slice:
+				fi.seq = seqTypeSlice
+				fn.fe = (*Encoder).kSlice
+				fn.fd = (*Decoder).kSlice
+			case reflect.Array:
+				fi.seq = seqTypeArray
+				fn.fe = (*Encoder).kSlice
+				fi.addrF = false
+				fi.addrD = false
+				rt2 := reflect.SliceOf(ti.elem)
+				fn.fd = func(d *Decoder, xf *codecFnInfo, xrv reflect.Value) {
+					d.cfer().get(rt2, true, false).fd(d, xf, xrv.Slice(0, xrv.Len()))
+				}
+				// fn.fd = (*Decoder).kArray
+			case reflect.Struct:
+				if ti.anyOmitEmpty {
+					fn.fe = (*Encoder).kStruct
+				} else {
+					fn.fe = (*Encoder).kStructNoOmitempty
+				}
+				fn.fd = (*Decoder).kStruct
+			case reflect.Map:
+				fn.fe = (*Encoder).kMap
+				fn.fd = (*Decoder).kMap
+			case reflect.Interface:
+				// encode: reflect.Interface are handled already by preEncodeValue
+				fn.fd = (*Decoder).kInterface
+				fn.fe = (*Encoder).kErr
+			default:
+				// reflect.Ptr and reflect.Interface are handled already by preEncodeValue
+				fn.fe = (*Encoder).kErr
+				fn.fd = (*Decoder).kErr
+			}
+		}
+	}
+	return
+}
+
+type codecFnPooler struct {
+	cf  *codecFner
+	cfp *sync.Pool
+	hh  Handle
+}
+
+func (d *codecFnPooler) cfer() *codecFner {
+	if d.cf == nil {
+		var v interface{}
+		d.cfp, v = pool.codecFner()
+		d.cf = v.(*codecFner)
+		d.cf.reset(d.hh)
+	}
+	return d.cf
+}
+
+func (d *codecFnPooler) alwaysAtEnd() {
+	if d.cf != nil {
+		d.cfp.Put(d.cf)
+		d.cf, d.cfp = nil, nil
+	}
+}
+
+// ----
+
+// these "checkOverflow" functions must be inlinable, and not call anybody.
+// Overflow means that the value cannot be represented without wrapping/overflow.
+// Overflow=false does not mean that the value can be represented without losing precision
+// (especially for floating point).
+
+type checkOverflow struct{}
+
+// func (checkOverflow) Float16(f float64) (overflow bool) {
+// 	panicv.errorf("unimplemented")
+// 	if f < 0 {
+// 		f = -f
+// 	}
+// 	return math.MaxFloat32 < f && f <= math.MaxFloat64
+// }
+
+func (checkOverflow) Float32(v float64) (overflow bool) {
+	if v < 0 {
+		v = -v
+	}
+	return math.MaxFloat32 < v && v <= math.MaxFloat64
+}
+func (checkOverflow) Uint(v uint64, bitsize uint8) (overflow bool) {
+	if bitsize == 0 || bitsize >= 64 || v == 0 {
+		return
+	}
+	if trunc := (v << (64 - bitsize)) >> (64 - bitsize); v != trunc {
+		overflow = true
+	}
+	return
+}
+func (checkOverflow) Int(v int64, bitsize uint8) (overflow bool) {
+	if bitsize == 0 || bitsize >= 64 || v == 0 {
+		return
+	}
+	if trunc := (v << (64 - bitsize)) >> (64 - bitsize); v != trunc {
+		overflow = true
+	}
+	return
+}
+func (checkOverflow) SignedInt(v uint64) (overflow bool) {
+	//e.g. -127 to 128 for int8
+	pos := (v >> 63) == 0
+	ui2 := v & 0x7fffffffffffffff
+	if pos {
+		if ui2 > math.MaxInt64 {
+			overflow = true
+		}
+	} else {
+		if ui2 > math.MaxInt64-1 {
+			overflow = true
+		}
+	}
+	return
+}
+
+func (x checkOverflow) Float32V(v float64) float64 {
+	if x.Float32(v) {
+		panicv.errorf("float32 overflow: %v", v)
+	}
+	return v
+}
+func (x checkOverflow) UintV(v uint64, bitsize uint8) uint64 {
+	if x.Uint(v, bitsize) {
+		panicv.errorf("uint64 overflow: %v", v)
+	}
+	return v
+}
+func (x checkOverflow) IntV(v int64, bitsize uint8) int64 {
+	if x.Int(v, bitsize) {
+		panicv.errorf("int64 overflow: %v", v)
+	}
+	return v
+}
+func (x checkOverflow) SignedIntV(v uint64) int64 {
+	if x.SignedInt(v) {
+		panicv.errorf("uint64 to int64 overflow: %v", v)
+	}
+	return int64(v)
+}
+
+// ------------------ SORT -----------------
+
+func isNaN(f float64) bool { return f != f }
+
+// -----------------------
+
+type ioFlusher interface {
+	Flush() error
+}
+
+type ioPeeker interface {
+	Peek(int) ([]byte, error)
+}
+
+type ioBuffered interface {
+	Buffered() int
+}
+
+// -----------------------
+
+type intSlice []int64
+type uintSlice []uint64
+
+// type uintptrSlice []uintptr
+type floatSlice []float64
+type boolSlice []bool
+type stringSlice []string
+
+// type bytesSlice [][]byte
+
+func (p intSlice) Len() int           { return len(p) }
+func (p intSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p intSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p uintSlice) Len() int           { return len(p) }
+func (p uintSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p uintSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// func (p uintptrSlice) Len() int           { return len(p) }
+// func (p uintptrSlice) Less(i, j int) bool { return p[i] < p[j] }
+// func (p uintptrSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p floatSlice) Len() int { return len(p) }
+func (p floatSlice) Less(i, j int) bool {
+	return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j])
+}
+func (p floatSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func (p stringSlice) Len() int           { return len(p) }
+func (p stringSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p stringSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// func (p bytesSlice) Len() int           { return len(p) }
+// func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 }
+// func (p bytesSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p boolSlice) Len() int           { return len(p) }
+func (p boolSlice) Less(i, j int) bool { return !p[i] && p[j] }
+func (p boolSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// ---------------------
+
+type intRv struct {
+	v int64
+	r reflect.Value
+}
+type intRvSlice []intRv
+type uintRv struct {
+	v uint64
+	r reflect.Value
+}
+type uintRvSlice []uintRv
+type floatRv struct {
+	v float64
+	r reflect.Value
+}
+type floatRvSlice []floatRv
+type boolRv struct {
+	v bool
+	r reflect.Value
+}
+type boolRvSlice []boolRv
+type stringRv struct {
+	v string
+	r reflect.Value
+}
+type stringRvSlice []stringRv
+type bytesRv struct {
+	v []byte
+	r reflect.Value
+}
+type bytesRvSlice []bytesRv
+type timeRv struct {
+	v time.Time
+	r reflect.Value
+}
+type timeRvSlice []timeRv
+
+func (p intRvSlice) Len() int           { return len(p) }
+func (p intRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
+func (p intRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p uintRvSlice) Len() int           { return len(p) }
+func (p uintRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
+func (p uintRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p floatRvSlice) Len() int { return len(p) }
+func (p floatRvSlice) Less(i, j int) bool {
+	return p[i].v < p[j].v || isNaN(p[i].v) && !isNaN(p[j].v)
+}
+func (p floatRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func (p stringRvSlice) Len() int           { return len(p) }
+func (p stringRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
+func (p stringRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p bytesRvSlice) Len() int           { return len(p) }
+func (p bytesRvSlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
+func (p bytesRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p boolRvSlice) Len() int           { return len(p) }
+func (p boolRvSlice) Less(i, j int) bool { return !p[i].v && p[j].v }
+func (p boolRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func (p timeRvSlice) Len() int           { return len(p) }
+func (p timeRvSlice) Less(i, j int) bool { return p[i].v.Before(p[j].v) }
+func (p timeRvSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// -----------------
+
+type bytesI struct {
+	v []byte
+	i interface{}
+}
+
+type bytesISlice []bytesI
+
+func (p bytesISlice) Len() int           { return len(p) }
+func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
+func (p bytesISlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// -----------------
+
+type set []uintptr
+
+func (s *set) add(v uintptr) (exists bool) {
+	// e.ci is always nil, or len >= 1
+	x := *s
+	if x == nil {
+		x = make([]uintptr, 1, 8)
+		x[0] = v
+		*s = x
+		return
+	}
+	// typically, length will be 1. make this perform.
+	if len(x) == 1 {
+		if j := x[0]; j == 0 {
+			x[0] = v
+		} else if j == v {
+			exists = true
+		} else {
+			x = append(x, v)
+			*s = x
+		}
+		return
+	}
+	// check if it exists
+	for _, j := range x {
+		if j == v {
+			exists = true
+			return
+		}
+	}
+	// try to replace a "deleted" slot
+	for i, j := range x {
+		if j == 0 {
+			x[i] = v
+			return
+		}
+	}
+	// if unable to replace deleted slot, just append it.
+	x = append(x, v)
+	*s = x
+	return
+}
+
+func (s *set) remove(v uintptr) (exists bool) {
+	x := *s
+	if len(x) == 0 {
+		return
+	}
+	if len(x) == 1 {
+		if x[0] == v {
+			x[0] = 0
+		}
+		return
+	}
+	for i, j := range x {
+		if j == v {
+			exists = true
+			x[i] = 0 // set it to 0, as way to delete it.
+			// copy(x[i:], x[i+1:])
+			// x = x[:len(x)-1]
+			return
+		}
+	}
+	return
+}
+
+// ------
+
+// bitset types are better than [256]bool, because they permit the whole
+// bitset array being on a single cache line and use less memory.
+
+// given x > 0 and n > 0 and x is exactly 2^n, then pos/x === pos>>n AND pos%x === pos&(x-1).
+// consequently, pos/32 === pos>>5, pos/16 === pos>>4, pos/8 === pos>>3, pos%8 == pos&7
+
+type bitset256 [32]byte
+
+func (x *bitset256) isset(pos byte) bool {
+	return x[pos>>3]&(1<<(pos&7)) != 0
+}
+func (x *bitset256) issetv(pos byte) byte {
+	return x[pos>>3] & (1 << (pos & 7))
+}
+func (x *bitset256) set(pos byte) {
+	x[pos>>3] |= (1 << (pos & 7))
+}
+
+// func (x *bitset256) unset(pos byte) {
+// 	x[pos>>3] &^= (1 << (pos & 7))
+// }
+
+type bitset128 [16]byte
+
+func (x *bitset128) isset(pos byte) bool {
+	return x[pos>>3]&(1<<(pos&7)) != 0
+}
+func (x *bitset128) set(pos byte) {
+	x[pos>>3] |= (1 << (pos & 7))
+}
+
+// func (x *bitset128) unset(pos byte) {
+// 	x[pos>>3] &^= (1 << (pos & 7))
+// }
+
+type bitset32 [4]byte
+
+func (x *bitset32) isset(pos byte) bool {
+	return x[pos>>3]&(1<<(pos&7)) != 0
+}
+func (x *bitset32) set(pos byte) {
+	x[pos>>3] |= (1 << (pos & 7))
+}
+
+// func (x *bitset32) unset(pos byte) {
+// 	x[pos>>3] &^= (1 << (pos & 7))
+// }
+
+// type bit2set256 [64]byte
+
+// func (x *bit2set256) set(pos byte, v1, v2 bool) {
+// 	var pos2 uint8 = (pos & 3) << 1 // returning 0, 2, 4 or 6
+// 	if v1 {
+// 		x[pos>>2] |= 1 << (pos2 + 1)
+// 	}
+// 	if v2 {
+// 		x[pos>>2] |= 1 << pos2
+// 	}
+// }
+// func (x *bit2set256) get(pos byte) uint8 {
+// 	var pos2 uint8 = (pos & 3) << 1     // returning 0, 2, 4 or 6
+// 	return x[pos>>2] << (6 - pos2) >> 6 // 11000000 -> 00000011
+// }
+
+// ------------
+
+type pooler struct {
+	dn                                          sync.Pool // for decNaked
+	cfn                                         sync.Pool // for codecFner
+	tiload                                      sync.Pool
+	strRv8, strRv16, strRv32, strRv64, strRv128 sync.Pool // for stringRV
+}
+
+func (p *pooler) init() {
+	p.strRv8.New = func() interface{} { return new([8]stringRv) }
+	p.strRv16.New = func() interface{} { return new([16]stringRv) }
+	p.strRv32.New = func() interface{} { return new([32]stringRv) }
+	p.strRv64.New = func() interface{} { return new([64]stringRv) }
+	p.strRv128.New = func() interface{} { return new([128]stringRv) }
+	p.dn.New = func() interface{} { x := new(decNaked); x.init(); return x }
+	p.tiload.New = func() interface{} { return new(typeInfoLoadArray) }
+	p.cfn.New = func() interface{} { return new(codecFner) }
+}
+
+func (p *pooler) stringRv8() (sp *sync.Pool, v interface{}) {
+	return &p.strRv8, p.strRv8.Get()
+}
+func (p *pooler) stringRv16() (sp *sync.Pool, v interface{}) {
+	return &p.strRv16, p.strRv16.Get()
+}
+func (p *pooler) stringRv32() (sp *sync.Pool, v interface{}) {
+	return &p.strRv32, p.strRv32.Get()
+}
+func (p *pooler) stringRv64() (sp *sync.Pool, v interface{}) {
+	return &p.strRv64, p.strRv64.Get()
+}
+func (p *pooler) stringRv128() (sp *sync.Pool, v interface{}) {
+	return &p.strRv128, p.strRv128.Get()
+}
+func (p *pooler) decNaked() (sp *sync.Pool, v interface{}) {
+	return &p.dn, p.dn.Get()
+}
+func (p *pooler) codecFner() (sp *sync.Pool, v interface{}) {
+	return &p.cfn, p.cfn.Get()
+}
+func (p *pooler) tiLoad() (sp *sync.Pool, v interface{}) {
+	return &p.tiload, p.tiload.Get()
+}
+
+// func (p *pooler) decNaked() (v *decNaked, f func(*decNaked) ) {
+// 	sp := &(p.dn)
+// 	vv := sp.Get()
+// 	return vv.(*decNaked), func(x *decNaked) { sp.Put(vv) }
+// }
+// func (p *pooler) decNakedGet() (v interface{}) {
+// 	return p.dn.Get()
+// }
+// func (p *pooler) codecFnerGet() (v interface{}) {
+// 	return p.cfn.Get()
+// }
+// func (p *pooler) tiLoadGet() (v interface{}) {
+// 	return p.tiload.Get()
+// }
+// func (p *pooler) decNakedPut(v interface{}) {
+// 	p.dn.Put(v)
+// }
+// func (p *pooler) codecFnerPut(v interface{}) {
+// 	p.cfn.Put(v)
+// }
+// func (p *pooler) tiLoadPut(v interface{}) {
+// 	p.tiload.Put(v)
+// }
+
+type panicHdl struct{}
+
+func (panicHdl) errorv(err error) {
+	if err != nil {
+		panic(err)
+	}
+}
+
+func (panicHdl) errorstr(message string) {
+	if message != "" {
+		panic(message)
+	}
+}
+
+func (panicHdl) errorf(format string, params ...interface{}) {
+	if format != "" {
+		if len(params) == 0 {
+			panic(format)
+		} else {
+			panic(fmt.Sprintf(format, params...))
+		}
+	}
+}
+
+type errstrDecorator interface {
+	wrapErrstr(interface{}, *error)
+}
+
+type errstrDecoratorDef struct{}
+
+func (errstrDecoratorDef) wrapErrstr(v interface{}, e *error) { *e = fmt.Errorf("%v", v) }
+
+type must struct{}
+
+func (must) String(s string, err error) string {
+	if err != nil {
+		panicv.errorv(err)
+	}
+	return s
+}
+func (must) Int(s int64, err error) int64 {
+	if err != nil {
+		panicv.errorv(err)
+	}
+	return s
+}
+func (must) Uint(s uint64, err error) uint64 {
+	if err != nil {
+		panicv.errorv(err)
+	}
+	return s
+}
+func (must) Float(s float64, err error) float64 {
+	if err != nil {
+		panicv.errorv(err)
+	}
+	return s
+}
+
+// xdebugf prints the message in red on the terminal.
+// Use it in place of fmt.Printf (which it calls internally)
+func xdebugf(pattern string, args ...interface{}) {
+	var delim string
+	if len(pattern) > 0 && pattern[len(pattern)-1] != '\n' {
+		delim = "\n"
+	}
+	fmt.Printf("\033[1;31m"+pattern+delim+"\033[0m", args...)
+}
+
+// func isImmutableKind(k reflect.Kind) (v bool) {
+// 	return false ||
+// 		k == reflect.Int ||
+// 		k == reflect.Int8 ||
+// 		k == reflect.Int16 ||
+// 		k == reflect.Int32 ||
+// 		k == reflect.Int64 ||
+// 		k == reflect.Uint ||
+// 		k == reflect.Uint8 ||
+// 		k == reflect.Uint16 ||
+// 		k == reflect.Uint32 ||
+// 		k == reflect.Uint64 ||
+// 		k == reflect.Uintptr ||
+// 		k == reflect.Float32 ||
+// 		k == reflect.Float64 ||
+// 		k == reflect.Bool ||
+// 		k == reflect.String
+// }
+
+// func timeLocUTCName(tzint int16) string {
+// 	if tzint == 0 {
+// 		return "UTC"
+// 	}
+// 	var tzname = []byte("UTC+00:00")
+// 	//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
+// 	//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
+// 	var tzhr, tzmin int16
+// 	if tzint < 0 {
+// 		tzname[3] = '-' // (TODO: verify. this works here)
+// 		tzhr, tzmin = -tzint/60, (-tzint)%60
+// 	} else {
+// 		tzhr, tzmin = tzint/60, tzint%60
+// 	}
+// 	tzname[4] = timeDigits[tzhr/10]
+// 	tzname[5] = timeDigits[tzhr%10]
+// 	tzname[7] = timeDigits[tzmin/10]
+// 	tzname[8] = timeDigits[tzmin%10]
+// 	return string(tzname)
+// 	//return time.FixedZone(string(tzname), int(tzint)*60)
+// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_internal.go b/vendor/github.com/ugorji/go/codec/helper_internal.go
new file mode 100644
index 0000000..0cbd665
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/helper_internal.go
@@ -0,0 +1,121 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+// All non-std package dependencies live in this file,
+// so porting to different environment is easy (just update functions).
+
+func pruneSignExt(v []byte, pos bool) (n int) {
+	if len(v) < 2 {
+	} else if pos && v[0] == 0 {
+		for ; v[n] == 0 && n+1 < len(v) && (v[n+1]&(1<<7) == 0); n++ {
+		}
+	} else if !pos && v[0] == 0xff {
+		for ; v[n] == 0xff && n+1 < len(v) && (v[n+1]&(1<<7) != 0); n++ {
+		}
+	}
+	return
+}
+
+// validate that this function is correct ...
+// culled from OGRE (Object-Oriented Graphics Rendering Engine)
+// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html)
+func halfFloatToFloatBits(yy uint16) (d uint32) {
+	y := uint32(yy)
+	s := (y >> 15) & 0x01
+	e := (y >> 10) & 0x1f
+	m := y & 0x03ff
+
+	if e == 0 {
+		if m == 0 { // plu or minus 0
+			return s << 31
+		}
+		// Denormalized number -- renormalize it
+		for (m & 0x00000400) == 0 {
+			m <<= 1
+			e -= 1
+		}
+		e += 1
+		const zz uint32 = 0x0400
+		m &= ^zz
+	} else if e == 31 {
+		if m == 0 { // Inf
+			return (s << 31) | 0x7f800000
+		}
+		return (s << 31) | 0x7f800000 | (m << 13) // NaN
+	}
+	e = e + (127 - 15)
+	m = m << 13
+	return (s << 31) | (e << 23) | m
+}
+
+// GrowCap will return a new capacity for a slice, given the following:
+//   - oldCap: current capacity
+//   - unit: in-memory size of an element
+//   - num: number of elements to add
+func growCap(oldCap, unit, num int) (newCap int) {
+	// appendslice logic (if cap < 1024, *2, else *1.25):
+	//   leads to many copy calls, especially when copying bytes.
+	//   bytes.Buffer model (2*cap + n): much better for bytes.
+	// smarter way is to take the byte-size of the appended element(type) into account
+
+	// maintain 3 thresholds:
+	// t1: if cap <= t1, newcap = 2x
+	// t2: if cap <= t2, newcap = 1.75x
+	// t3: if cap <= t3, newcap = 1.5x
+	//     else          newcap = 1.25x
+	//
+	// t1, t2, t3 >= 1024 always.
+	// i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same)
+	//
+	// With this, appending for bytes increase by:
+	//    100% up to 4K
+	//     75% up to 8K
+	//     50% up to 16K
+	//     25% beyond that
+
+	// unit can be 0 e.g. for struct{}{}; handle that appropriately
+	var t1, t2, t3 int // thresholds
+	if unit <= 1 {
+		t1, t2, t3 = 4*1024, 8*1024, 16*1024
+	} else if unit < 16 {
+		t3 = 16 / unit * 1024
+		t1 = t3 * 1 / 4
+		t2 = t3 * 2 / 4
+	} else {
+		t1, t2, t3 = 1024, 1024, 1024
+	}
+
+	var x int // temporary variable
+
+	// x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively
+	if oldCap <= t1 { // [0,t1]
+		x = 8
+	} else if oldCap > t3 { // (t3,infinity]
+		x = 5
+	} else if oldCap <= t2 { // (t1,t2]
+		x = 7
+	} else { // (t2,t3]
+		x = 6
+	}
+	newCap = x * oldCap / 4
+
+	if num > 0 {
+		newCap += num
+	}
+
+	// ensure newCap is a multiple of 64 (if it is > 64) or 16.
+	if newCap > 64 {
+		if x = newCap % 64; x != 0 {
+			x = newCap / 64
+			newCap = 64 * (x + 1)
+		}
+	} else {
+		if x = newCap % 16; x != 0 {
+			x = newCap / 16
+			newCap = 16 * (x + 1)
+		}
+	}
+	return
+}
diff --git a/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
new file mode 100644
index 0000000..fd52690
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
@@ -0,0 +1,272 @@
+// +build !go1.7 safe appengine
+
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"reflect"
+	"sync/atomic"
+	"time"
+)
+
+const safeMode = true
+
+// stringView returns a view of the []byte as a string.
+// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
+// In regular safe mode, it is an allocation and copy.
+//
+// Usage: Always maintain a reference to v while result of this call is in use,
+//        and call keepAlive4BytesView(v) at point where done with view.
+func stringView(v []byte) string {
+	return string(v)
+}
+
+// bytesView returns a view of the string as a []byte.
+// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
+// In regular safe mode, it is an allocation and copy.
+//
+// Usage: Always maintain a reference to v while result of this call is in use,
+//        and call keepAlive4BytesView(v) at point where done with view.
+func bytesView(v string) []byte {
+	return []byte(v)
+}
+
+func definitelyNil(v interface{}) bool {
+	// this is a best-effort option.
+	// We just return false, so we don't unnecessarily incur the cost of reflection this early.
+	return false
+}
+
+func rv2i(rv reflect.Value) interface{} {
+	return rv.Interface()
+}
+
+func rt2id(rt reflect.Type) uintptr {
+	return reflect.ValueOf(rt).Pointer()
+}
+
+func rv2rtid(rv reflect.Value) uintptr {
+	return reflect.ValueOf(rv.Type()).Pointer()
+}
+
+func i2rtid(i interface{}) uintptr {
+	return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
+}
+
+// --------------------------
+
+func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
+	switch v.Kind() {
+	case reflect.Invalid:
+		return true
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		if deref {
+			if v.IsNil() {
+				return true
+			}
+			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
+		}
+		return v.IsNil()
+	case reflect.Struct:
+		return isEmptyStruct(v, tinfos, deref, checkStruct)
+	}
+	return false
+}
+
+// --------------------------
+// type ptrToRvMap struct{}
+
+// func (*ptrToRvMap) init() {}
+// func (*ptrToRvMap) get(i interface{}) reflect.Value {
+// 	return reflect.ValueOf(i).Elem()
+// }
+
+// --------------------------
+type atomicTypeInfoSlice struct { // expected to be 2 words
+	v atomic.Value
+}
+
+func (x *atomicTypeInfoSlice) load() []rtid2ti {
+	i := x.v.Load()
+	if i == nil {
+		return nil
+	}
+	return i.([]rtid2ti)
+}
+
+func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
+	x.v.Store(p)
+}
+
+// --------------------------
+func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
+	rv.SetBytes(d.rawBytes())
+}
+
+func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
+	rv.SetString(d.d.DecodeString())
+}
+
+func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
+	rv.SetBool(d.d.DecodeBool())
+}
+
+func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
+	rv.Set(reflect.ValueOf(d.d.DecodeTime()))
+}
+
+func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
+	fv := d.d.DecodeFloat64()
+	if chkOvf.Float32(fv) {
+		d.errorf("float32 overflow: %v", fv)
+	}
+	rv.SetFloat(fv)
+}
+
+func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
+	rv.SetFloat(d.d.DecodeFloat64())
+}
+
+func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
+	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
+}
+
+func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
+	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
+}
+
+func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
+	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
+}
+
+func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
+	rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
+}
+
+func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
+	rv.SetInt(d.d.DecodeInt64())
+}
+
+func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+}
+
+func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+}
+
+func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
+}
+
+func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
+}
+
+func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
+}
+
+func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
+	rv.SetUint(d.d.DecodeUint64())
+}
+
+// ----------------
+
+func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeBool(rv.Bool())
+}
+
+func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeTime(rv2i(rv).(time.Time))
+}
+
+func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeString(cUTF8, rv.String())
+}
+
+func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeFloat64(rv.Float())
+}
+
+func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeFloat32(float32(rv.Float()))
+}
+
+func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeInt(rv.Int())
+}
+
+func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeInt(rv.Int())
+}
+
+func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeInt(rv.Int())
+}
+
+func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeInt(rv.Int())
+}
+
+func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeInt(rv.Int())
+}
+
+func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
+	e.e.EncodeUint(rv.Uint())
+}
+
+// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
+// //
+// // Usage: call this at point where done with the bytes view.
+// func keepAlive4BytesView(v string) {}
+
+// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
+// //
+// // Usage: call this at point where done with the string view.
+// func keepAlive4StringView(v []byte) {}
+
+// func definitelyNil(v interface{}) bool {
+// 	rv := reflect.ValueOf(v)
+// 	switch rv.Kind() {
+// 	case reflect.Invalid:
+// 		return true
+// 	case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
+// 		return rv.IsNil()
+// 	default:
+// 		return false
+// 	}
+// }
diff --git a/vendor/github.com/ugorji/go/codec/helper_unsafe.go b/vendor/github.com/ugorji/go/codec/helper_unsafe.go
new file mode 100644
index 0000000..e3df60a
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/helper_unsafe.go
@@ -0,0 +1,639 @@
+// +build !safe
+// +build !appengine
+// +build go1.7
+
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"reflect"
+	"sync/atomic"
+	"time"
+	"unsafe"
+)
+
+// This file has unsafe variants of some helper methods.
+// NOTE: See helper_not_unsafe.go for the usage information.
+
+// var zeroRTv [4]uintptr
+
+const safeMode = false
+const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
+
+type unsafeString struct {
+	Data unsafe.Pointer
+	Len  int
+}
+
+type unsafeSlice struct {
+	Data unsafe.Pointer
+	Len  int
+	Cap  int
+}
+
+type unsafeIntf struct {
+	typ  unsafe.Pointer
+	word unsafe.Pointer
+}
+
+type unsafeReflectValue struct {
+	typ  unsafe.Pointer
+	ptr  unsafe.Pointer
+	flag uintptr
+}
+
+func stringView(v []byte) string {
+	if len(v) == 0 {
+		return ""
+	}
+	bx := (*unsafeSlice)(unsafe.Pointer(&v))
+	return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
+}
+
+func bytesView(v string) []byte {
+	if len(v) == 0 {
+		return zeroByteSlice
+	}
+	sx := (*unsafeString)(unsafe.Pointer(&v))
+	return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
+}
+
+func definitelyNil(v interface{}) bool {
+	// There is no global way of checking if an interface is nil.
+	// For true references (map, ptr, func, chan), you can just look
+	// at the word of the interface. However, for slices, you have to dereference
+	// the word, and get a pointer to the 3-word interface value.
+	//
+	// However, the following are cheap calls
+	// - TypeOf(interface): cheap 2-line call.
+	// - ValueOf(interface{}): expensive
+	// - type.Kind: cheap call through an interface
+	// - Value.Type(): cheap call
+	//                 except it's a method value (e.g. r.Read, which implies that it is a Func)
+
+	return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
+}
+
+func rv2i(rv reflect.Value) interface{} {
+	// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
+	//
+	// Currently, we use this fragile method that taps into implememtation details from
+	// the source go stdlib reflect/value.go, and trims the implementation.
+
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
+	var ptr unsafe.Pointer
+	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
+		ptr = *(*unsafe.Pointer)(urv.ptr)
+	} else {
+		ptr = urv.ptr
+	}
+	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
+}
+
+func rt2id(rt reflect.Type) uintptr {
+	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
+}
+
+func rv2rtid(rv reflect.Value) uintptr {
+	return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
+}
+
+func i2rtid(i interface{}) uintptr {
+	return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
+}
+
+// --------------------------
+
+func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
+	if urv.flag == 0 {
+		return true
+	}
+	switch v.Kind() {
+	case reflect.Invalid:
+		return true
+	case reflect.String:
+		return (*unsafeString)(urv.ptr).Len == 0
+	case reflect.Slice:
+		return (*unsafeSlice)(urv.ptr).Len == 0
+	case reflect.Bool:
+		return !*(*bool)(urv.ptr)
+	case reflect.Int:
+		return *(*int)(urv.ptr) == 0
+	case reflect.Int8:
+		return *(*int8)(urv.ptr) == 0
+	case reflect.Int16:
+		return *(*int16)(urv.ptr) == 0
+	case reflect.Int32:
+		return *(*int32)(urv.ptr) == 0
+	case reflect.Int64:
+		return *(*int64)(urv.ptr) == 0
+	case reflect.Uint:
+		return *(*uint)(urv.ptr) == 0
+	case reflect.Uint8:
+		return *(*uint8)(urv.ptr) == 0
+	case reflect.Uint16:
+		return *(*uint16)(urv.ptr) == 0
+	case reflect.Uint32:
+		return *(*uint32)(urv.ptr) == 0
+	case reflect.Uint64:
+		return *(*uint64)(urv.ptr) == 0
+	case reflect.Uintptr:
+		return *(*uintptr)(urv.ptr) == 0
+	case reflect.Float32:
+		return *(*float32)(urv.ptr) == 0
+	case reflect.Float64:
+		return *(*float64)(urv.ptr) == 0
+	case reflect.Interface:
+		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
+		if deref {
+			if isnil {
+				return true
+			}
+			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
+		}
+		return isnil
+	case reflect.Ptr:
+		// isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
+		isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
+		if deref {
+			if isnil {
+				return true
+			}
+			return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
+		}
+		return isnil
+	case reflect.Struct:
+		return isEmptyStruct(v, tinfos, deref, checkStruct)
+	case reflect.Map, reflect.Array, reflect.Chan:
+		return v.Len() == 0
+	}
+	return false
+}
+
+// --------------------------
+
+// atomicTypeInfoSlice contains length and pointer to the array for a slice.
+// It is expected to be 2 words.
+//
+// Previously, we atomically loaded and stored the length and array pointer separately,
+// which could lead to some races.
+// We now just atomically store and load the pointer to the value directly.
+
+type atomicTypeInfoSlice struct { // expected to be 2 words
+	l int            // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
+	v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
+}
+
+func (x *atomicTypeInfoSlice) load() []rtid2ti {
+	xp := unsafe.Pointer(x)
+	x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
+	if x2.l == 0 {
+		return nil
+	}
+	return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
+}
+
+func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
+	s := (*unsafeSlice)(unsafe.Pointer(&p))
+	xp := unsafe.Pointer(x)
+	atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
+}
+
+// --------------------------
+func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*[]byte)(urv.ptr) = d.rawBytes()
+}
+
+func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*string)(urv.ptr) = d.d.DecodeString()
+}
+
+func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*bool)(urv.ptr) = d.d.DecodeBool()
+}
+
+func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*time.Time)(urv.ptr) = d.d.DecodeTime()
+}
+
+func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
+	fv := d.d.DecodeFloat64()
+	if chkOvf.Float32(fv) {
+		d.errorf("float32 overflow: %v", fv)
+	}
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*float32)(urv.ptr) = float32(fv)
+}
+
+func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*float64)(urv.ptr) = d.d.DecodeFloat64()
+}
+
+func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
+}
+
+func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
+}
+
+func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
+}
+
+func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
+}
+
+func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*int64)(urv.ptr) = d.d.DecodeInt64()
+}
+
+func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+}
+
+func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
+}
+
+func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
+}
+
+func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
+}
+
+func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
+}
+
+func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
+	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	*(*uint64)(urv.ptr) = d.d.DecodeUint64()
+}
+
+// ------------
+
+func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeBool(*(*bool)(v.ptr))
+}
+
+func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeTime(*(*time.Time)(v.ptr))
+}
+
+func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeString(cUTF8, *(*string)(v.ptr))
+}
+
+func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeFloat64(*(*float64)(v.ptr))
+}
+
+func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeFloat32(*(*float32)(v.ptr))
+}
+
+func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeInt(int64(*(*int)(v.ptr)))
+}
+
+func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeInt(int64(*(*int8)(v.ptr)))
+}
+
+func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeInt(int64(*(*int16)(v.ptr)))
+}
+
+func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeInt(int64(*(*int32)(v.ptr)))
+}
+
+func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeInt(int64(*(*int64)(v.ptr)))
+}
+
+func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
+}
+
+func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
+}
+
+func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
+}
+
+func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
+}
+
+func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
+}
+
+func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
+	v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+	e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
+}
+
+// ------------
+
+// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
+// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+// 	// if urv.flag&unsafeFlagIndir != 0 {
+// 	// 	urv.ptr = *(*unsafe.Pointer)(urv.ptr)
+// 	// }
+// 	*(*[]byte)(urv.ptr) = d.rawBytes()
+// }
+
+// func rv0t(rt reflect.Type) reflect.Value {
+// 	ut := (*unsafeIntf)(unsafe.Pointer(&rt))
+// 	// we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
+// 	uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
+// 	return *(*reflect.Value)(unsafe.Pointer(&uv})
+// }
+
+// func rv2i(rv reflect.Value) interface{} {
+// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+// 	// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
+// 	var ptr unsafe.Pointer
+// 	// kk := reflect.Kind(urv.flag & (1<<5 - 1))
+// 	// if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
+// 	if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
+// 		ptr = *(*unsafe.Pointer)(urv.ptr)
+// 	} else {
+// 		ptr = urv.ptr
+// 	}
+// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
+// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
+// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// }
+
+// func definitelyNil(v interface{}) bool {
+// 	var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
+// 	if ui.word == nil {
+// 		return true
+// 	}
+// 	var tk = reflect.TypeOf(v).Kind()
+// 	return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
+// 	fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
+// 	v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
+// }
+
+// func keepAlive4BytesView(v string) {
+// 	runtime.KeepAlive(v)
+// }
+
+// func keepAlive4StringView(v []byte) {
+// 	runtime.KeepAlive(v)
+// }
+
+// func rt2id(rt reflect.Type) uintptr {
+// 	return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
+// 	// var i interface{} = rt
+// 	// // ui := (*unsafeIntf)(unsafe.Pointer(&i))
+// 	// return ((*unsafeIntf)(unsafe.Pointer(&i))).word
+// }
+
+// func rv2i(rv reflect.Value) interface{} {
+// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+// 	// non-reference type: already indir
+// 	// reference type: depend on flagIndir property ('cos maybe was double-referenced)
+// 	// const (unsafeRvFlagKindMask    = 1<<5 - 1 , unsafeRvFlagIndir       = 1 << 7 )
+// 	// rvk := reflect.Kind(urv.flag & (1<<5 - 1))
+// 	// if (rvk == reflect.Chan ||
+// 	// 	rvk == reflect.Func ||
+// 	// 	rvk == reflect.Interface ||
+// 	// 	rvk == reflect.Map ||
+// 	// 	rvk == reflect.Ptr ||
+// 	// 	rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
+// 	// 	fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
+// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
+// 	// }
+// 	if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
+// 		// fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
+// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
+// 	}
+// 	// fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
+// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// }
+
+// const (
+// 	unsafeRvFlagKindMask    = 1<<5 - 1
+// 	unsafeRvKindDirectIface = 1 << 5
+// 	unsafeRvFlagIndir       = 1 << 7
+// 	unsafeRvFlagAddr        = 1 << 8
+// 	unsafeRvFlagMethod      = 1 << 9
+
+// 	_USE_RV_INTERFACE bool = false
+// 	_UNSAFE_RV_DEBUG       = true
+// )
+
+// type unsafeRtype struct {
+// 	_    [2]uintptr
+// 	_    uint32
+// 	_    uint8
+// 	_    uint8
+// 	_    uint8
+// 	kind uint8
+// 	_    [2]uintptr
+// 	_    int32
+// }
+
+// func _rv2i(rv reflect.Value) interface{} {
+// 	// Note: From use,
+// 	//   - it's never an interface
+// 	//   - the only calls here are for ifaceIndir types.
+// 	//     (though that conditional is wrong)
+// 	//     To know for sure, we need the value of t.kind (which is not exposed).
+// 	//
+// 	// Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
+// 	//    - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
+// 	//    - Type Direct,   Value indirect: ==> map???
+// 	//    - Type Direct,   Value direct:   ==> pointers, unsafe.Pointer, func, chan, map
+// 	//
+// 	// TRANSLATES TO:
+// 	//    if typeIndirect { } else if valueIndirect { } else { }
+// 	//
+// 	// Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
+
+// 	if _USE_RV_INTERFACE {
+// 		return rv.Interface()
+// 	}
+// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+
+// 	// if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
+// 	// 	println("***** IS flag method or interface: delegating to rv.Interface()")
+// 	// 	return rv.Interface()
+// 	// }
+
+// 	// if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
+// 	// 	println("***** IS Interface: delegate to rv.Interface")
+// 	// 	return rv.Interface()
+// 	// }
+// 	// if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
+// 	// 	if urv.flag&unsafeRvFlagAddr == 0 {
+// 	// 		println("***** IS ifaceIndir typ")
+// 	// 		// ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
+// 	// 		// return *(*interface{})(unsafe.Pointer(&ui))
+// 	// 		// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// 	// 	}
+// 	// } else if urv.flag&unsafeRvFlagIndir != 0 {
+// 	// 	println("***** IS flagindir")
+// 	// 	// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
+// 	// } else {
+// 	// 	println("***** NOT flagindir")
+// 	// 	return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// 	// }
+// 	// println("***** default: delegate to rv.Interface")
+
+// 	urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
+// 	if _UNSAFE_RV_DEBUG {
+// 		fmt.Printf(">>>> start: %v: ", rv.Type())
+// 		fmt.Printf("%v - %v\n", *urv, *urt)
+// 	}
+// 	if urt.kind&unsafeRvKindDirectIface == 0 {
+// 		if _UNSAFE_RV_DEBUG {
+// 			fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
+// 		}
+// 		// println("***** IS ifaceIndir typ")
+// 		// if true || urv.flag&unsafeRvFlagAddr == 0 {
+// 		// 	// println("    ***** IS NOT addr")
+// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// 		// }
+// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
+// 		if _UNSAFE_RV_DEBUG {
+// 			fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
+// 		}
+// 		// println("***** IS flagindir")
+// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
+// 	} else {
+// 		if _UNSAFE_RV_DEBUG {
+// 			fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
+// 		}
+// 		// println("***** NOT flagindir")
+// 		return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
+// 	}
+// 	// println("***** default: delegating to rv.Interface()")
+// 	// return rv.Interface()
+// }
+
+// var staticM0 = make(map[string]uint64)
+// var staticI0 = (int32)(-5)
+
+// func staticRv2iTest() {
+// 	i0 := (int32)(-5)
+// 	m0 := make(map[string]uint16)
+// 	m0["1"] = 1
+// 	for _, i := range []interface{}{
+// 		(int)(7),
+// 		(uint)(8),
+// 		(int16)(-9),
+// 		(uint16)(19),
+// 		(uintptr)(77),
+// 		(bool)(true),
+// 		float32(-32.7),
+// 		float64(64.9),
+// 		complex(float32(19), 5),
+// 		complex(float64(-32), 7),
+// 		[4]uint64{1, 2, 3, 4},
+// 		(chan<- int)(nil), // chan,
+// 		rv2i,              // func
+// 		io.Writer(ioutil.Discard),
+// 		make(map[string]uint),
+// 		(map[string]uint)(nil),
+// 		staticM0,
+// 		m0,
+// 		&m0,
+// 		i0,
+// 		&i0,
+// 		&staticI0,
+// 		&staticM0,
+// 		[]uint32{6, 7, 8},
+// 		"abc",
+// 		Raw{},
+// 		RawExt{},
+// 		&Raw{},
+// 		&RawExt{},
+// 		unsafe.Pointer(&i0),
+// 	} {
+// 		i2 := rv2i(reflect.ValueOf(i))
+// 		eq := reflect.DeepEqual(i, i2)
+// 		fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
+// 	}
+// 	// os.Exit(0)
+// }
+
+// func init() {
+// 	staticRv2iTest()
+// }
+
+// func rv2i(rv reflect.Value) interface{} {
+// 	if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
+// 		return rv.Interface()
+// 	}
+// 	// var i interface{}
+// 	// ui := (*unsafeIntf)(unsafe.Pointer(&i))
+// 	var ui unsafeIntf
+// 	urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
+// 	// fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
+// 	if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
+// 		if urv.flag&unsafeRvFlagAddr != 0 {
+// 			println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
+// 			return rv.Interface()
+// 		}
+// 		println("****** indirect type/kind")
+// 		ui.word = urv.ptr
+// 	} else if urv.flag&unsafeRvFlagIndir != 0 {
+// 		println("****** unsafe rv flag indir")
+// 		ui.word = *(*unsafe.Pointer)(urv.ptr)
+// 	} else {
+// 		println("****** default: assign prt to word directly")
+// 		ui.word = urv.ptr
+// 	}
+// 	// ui.word = urv.ptr
+// 	ui.typ = urv.typ
+// 	// fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
+// 	// fmt.Printf("(binary)   ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
+// 	return *(*interface{})(unsafe.Pointer(&ui))
+// 	// return i
+// }
diff --git a/vendor/github.com/ugorji/go/codec/json.go b/vendor/github.com/ugorji/go/codec/json.go
new file mode 100644
index 0000000..bdd1996
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/json.go
@@ -0,0 +1,1423 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+// By default, this json support uses base64 encoding for bytes, because you cannot
+// store and read any arbitrary string in json (only unicode).
+// However, the user can configre how to encode/decode bytes.
+//
+// This library specifically supports UTF-8 for encoding and decoding only.
+//
+// Note that the library will happily encode/decode things which are not valid
+// json e.g. a map[int64]string. We do it for consistency. With valid json,
+// we will encode and decode appropriately.
+// Users can specify their map type if necessary to force it.
+//
+// Note:
+//   - we cannot use strconv.Quote and strconv.Unquote because json quotes/unquotes differently.
+//     We implement it here.
+
+// Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver
+// MUST not call one-another.
+
+import (
+	"bytes"
+	"encoding/base64"
+	"math"
+	"reflect"
+	"strconv"
+	"time"
+	"unicode"
+	"unicode/utf16"
+	"unicode/utf8"
+)
+
+//--------------------------------
+
+var jsonLiterals = [...]byte{
+	'"', 't', 'r', 'u', 'e', '"',
+	'"', 'f', 'a', 'l', 's', 'e', '"',
+	'"', 'n', 'u', 'l', 'l', '"',
+}
+
+const (
+	jsonLitTrueQ  = 0
+	jsonLitTrue   = 1
+	jsonLitFalseQ = 6
+	jsonLitFalse  = 7
+	jsonLitNullQ  = 13
+	jsonLitNull   = 14
+)
+
+const (
+	jsonU4Chk2 = '0'
+	jsonU4Chk1 = 'a' - 10
+	jsonU4Chk0 = 'A' - 10
+
+	jsonScratchArrayLen = 64
+)
+
+const (
+	// If !jsonValidateSymbols, decoding will be faster, by skipping some checks:
+	//   - If we see first character of null, false or true,
+	//     do not validate subsequent characters.
+	//   - e.g. if we see a n, assume null and skip next 3 characters,
+	//     and do not validate they are ull.
+	// P.S. Do not expect a significant decoding boost from this.
+	jsonValidateSymbols = true
+
+	jsonSpacesOrTabsLen = 128
+
+	jsonAlwaysReturnInternString = false
+)
+
+var (
+	// jsonTabs and jsonSpaces are used as caches for indents
+	jsonTabs, jsonSpaces [jsonSpacesOrTabsLen]byte
+
+	jsonCharHtmlSafeSet   bitset128
+	jsonCharSafeSet       bitset128
+	jsonCharWhitespaceSet bitset256
+	jsonNumSet            bitset256
+)
+
+func init() {
+	for i := 0; i < jsonSpacesOrTabsLen; i++ {
+		jsonSpaces[i] = ' '
+		jsonTabs[i] = '\t'
+	}
+
+	// populate the safe values as true: note: ASCII control characters are (0-31)
+	// jsonCharSafeSet:     all true except (0-31) " \
+	// jsonCharHtmlSafeSet: all true except (0-31) " \ < > &
+	var i byte
+	for i = 32; i < utf8.RuneSelf; i++ {
+		switch i {
+		case '"', '\\':
+		case '<', '>', '&':
+			jsonCharSafeSet.set(i) // = true
+		default:
+			jsonCharSafeSet.set(i)
+			jsonCharHtmlSafeSet.set(i)
+		}
+	}
+	for i = 0; i <= utf8.RuneSelf; i++ {
+		switch i {
+		case ' ', '\t', '\r', '\n':
+			jsonCharWhitespaceSet.set(i)
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-':
+			jsonNumSet.set(i)
+		}
+	}
+}
+
+// ----------------
+
+type jsonEncDriverTypical struct {
+	w encWriter
+	// w  *encWriterSwitch
+	b  *[jsonScratchArrayLen]byte
+	tw bool // term white space
+	c  containerState
+}
+
+func (e *jsonEncDriverTypical) typical() {}
+
+func (e *jsonEncDriverTypical) reset(ee *jsonEncDriver) {
+	e.w = ee.ew
+	// e.w = &ee.e.encWriterSwitch
+	e.b = &ee.b
+	e.tw = ee.h.TermWhitespace
+	e.c = 0
+}
+
+func (e *jsonEncDriverTypical) WriteArrayStart(length int) {
+	e.w.writen1('[')
+	e.c = containerArrayStart
+}
+
+func (e *jsonEncDriverTypical) WriteArrayElem() {
+	if e.c != containerArrayStart {
+		e.w.writen1(',')
+	}
+	e.c = containerArrayElem
+}
+
+func (e *jsonEncDriverTypical) WriteArrayEnd() {
+	e.w.writen1(']')
+	e.c = containerArrayEnd
+}
+
+func (e *jsonEncDriverTypical) WriteMapStart(length int) {
+	e.w.writen1('{')
+	e.c = containerMapStart
+}
+
+func (e *jsonEncDriverTypical) WriteMapElemKey() {
+	if e.c != containerMapStart {
+		e.w.writen1(',')
+	}
+	e.c = containerMapKey
+}
+
+func (e *jsonEncDriverTypical) WriteMapElemValue() {
+	e.w.writen1(':')
+	e.c = containerMapValue
+}
+
+func (e *jsonEncDriverTypical) WriteMapEnd() {
+	e.w.writen1('}')
+	e.c = containerMapEnd
+}
+
+func (e *jsonEncDriverTypical) EncodeBool(b bool) {
+	if b {
+		e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
+	} else {
+		e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
+	}
+}
+
+func (e *jsonEncDriverTypical) EncodeFloat64(f float64) {
+	fmt, prec := jsonFloatStrconvFmtPrec(f)
+	e.w.writeb(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
+}
+
+func (e *jsonEncDriverTypical) EncodeInt(v int64) {
+	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
+}
+
+func (e *jsonEncDriverTypical) EncodeUint(v uint64) {
+	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
+}
+
+func (e *jsonEncDriverTypical) EncodeFloat32(f float32) {
+	e.EncodeFloat64(float64(f))
+}
+
+func (e *jsonEncDriverTypical) atEndOfEncode() {
+	if e.tw {
+		e.w.writen1(' ')
+	}
+}
+
+// ----------------
+
+type jsonEncDriverGeneric struct {
+	w encWriter // encWriter // *encWriterSwitch
+	b *[jsonScratchArrayLen]byte
+	c containerState
+	// ds string // indent string
+	di int8    // indent per
+	d  bool    // indenting?
+	dt bool    // indent using tabs
+	dl uint16  // indent level
+	ks bool    // map key as string
+	is byte    // integer as string
+	tw bool    // term white space
+	_  [7]byte // padding
+}
+
+// indent is done as below:
+//   - newline and indent are added before each mapKey or arrayElem
+//   - newline and indent are added before each ending,
+//     except there was no entry (so we can have {} or [])
+
+func (e *jsonEncDriverGeneric) reset(ee *jsonEncDriver) {
+	e.w = ee.ew
+	e.b = &ee.b
+	e.tw = ee.h.TermWhitespace
+	e.c = 0
+	e.d, e.dt, e.dl, e.di = false, false, 0, 0
+	h := ee.h
+	if h.Indent > 0 {
+		e.d = true
+		e.di = int8(h.Indent)
+	} else if h.Indent < 0 {
+		e.d = true
+		e.dt = true
+		e.di = int8(-h.Indent)
+	}
+	e.ks = h.MapKeyAsString
+	e.is = h.IntegerAsString
+}
+
+func (e *jsonEncDriverGeneric) WriteArrayStart(length int) {
+	if e.d {
+		e.dl++
+	}
+	e.w.writen1('[')
+	e.c = containerArrayStart
+}
+
+func (e *jsonEncDriverGeneric) WriteArrayElem() {
+	if e.c != containerArrayStart {
+		e.w.writen1(',')
+	}
+	if e.d {
+		e.writeIndent()
+	}
+	e.c = containerArrayElem
+}
+
+func (e *jsonEncDriverGeneric) WriteArrayEnd() {
+	if e.d {
+		e.dl--
+		if e.c != containerArrayStart {
+			e.writeIndent()
+		}
+	}
+	e.w.writen1(']')
+	e.c = containerArrayEnd
+}
+
+func (e *jsonEncDriverGeneric) WriteMapStart(length int) {
+	if e.d {
+		e.dl++
+	}
+	e.w.writen1('{')
+	e.c = containerMapStart
+}
+
+func (e *jsonEncDriverGeneric) WriteMapElemKey() {
+	if e.c != containerMapStart {
+		e.w.writen1(',')
+	}
+	if e.d {
+		e.writeIndent()
+	}
+	e.c = containerMapKey
+}
+
+func (e *jsonEncDriverGeneric) WriteMapElemValue() {
+	if e.d {
+		e.w.writen2(':', ' ')
+	} else {
+		e.w.writen1(':')
+	}
+	e.c = containerMapValue
+}
+
+func (e *jsonEncDriverGeneric) WriteMapEnd() {
+	if e.d {
+		e.dl--
+		if e.c != containerMapStart {
+			e.writeIndent()
+		}
+	}
+	e.w.writen1('}')
+	e.c = containerMapEnd
+}
+
+func (e *jsonEncDriverGeneric) writeIndent() {
+	e.w.writen1('\n')
+	x := int(e.di) * int(e.dl)
+	if e.dt {
+		for x > jsonSpacesOrTabsLen {
+			e.w.writeb(jsonTabs[:])
+			x -= jsonSpacesOrTabsLen
+		}
+		e.w.writeb(jsonTabs[:x])
+	} else {
+		for x > jsonSpacesOrTabsLen {
+			e.w.writeb(jsonSpaces[:])
+			x -= jsonSpacesOrTabsLen
+		}
+		e.w.writeb(jsonSpaces[:x])
+	}
+}
+
+func (e *jsonEncDriverGeneric) EncodeBool(b bool) {
+	if e.ks && e.c == containerMapKey {
+		if b {
+			e.w.writeb(jsonLiterals[jsonLitTrueQ : jsonLitTrueQ+6])
+		} else {
+			e.w.writeb(jsonLiterals[jsonLitFalseQ : jsonLitFalseQ+7])
+		}
+	} else {
+		if b {
+			e.w.writeb(jsonLiterals[jsonLitTrue : jsonLitTrue+4])
+		} else {
+			e.w.writeb(jsonLiterals[jsonLitFalse : jsonLitFalse+5])
+		}
+	}
+}
+
+func (e *jsonEncDriverGeneric) EncodeFloat64(f float64) {
+	// instead of using 'g', specify whether to use 'e' or 'f'
+	fmt, prec := jsonFloatStrconvFmtPrec(f)
+
+	var blen int
+	if e.ks && e.c == containerMapKey {
+		blen = 2 + len(strconv.AppendFloat(e.b[1:1], f, fmt, prec, 64))
+		e.b[0] = '"'
+		e.b[blen-1] = '"'
+	} else {
+		blen = len(strconv.AppendFloat(e.b[:0], f, fmt, prec, 64))
+	}
+	e.w.writeb(e.b[:blen])
+}
+
+func (e *jsonEncDriverGeneric) EncodeInt(v int64) {
+	x := e.is
+	if x == 'A' || x == 'L' && (v > 1<<53 || v < -(1<<53)) || (e.ks && e.c == containerMapKey) {
+		blen := 2 + len(strconv.AppendInt(e.b[1:1], v, 10))
+		e.b[0] = '"'
+		e.b[blen-1] = '"'
+		e.w.writeb(e.b[:blen])
+		return
+	}
+	e.w.writeb(strconv.AppendInt(e.b[:0], v, 10))
+}
+
+func (e *jsonEncDriverGeneric) EncodeUint(v uint64) {
+	x := e.is
+	if x == 'A' || x == 'L' && v > 1<<53 || (e.ks && e.c == containerMapKey) {
+		blen := 2 + len(strconv.AppendUint(e.b[1:1], v, 10))
+		e.b[0] = '"'
+		e.b[blen-1] = '"'
+		e.w.writeb(e.b[:blen])
+		return
+	}
+	e.w.writeb(strconv.AppendUint(e.b[:0], v, 10))
+}
+
+func (e *jsonEncDriverGeneric) EncodeFloat32(f float32) {
+	// e.encodeFloat(float64(f), 32)
+	// always encode all floats as IEEE 64-bit floating point.
+	// It also ensures that we can decode in full precision even if into a float32,
+	// as what is written is always to float64 precision.
+	e.EncodeFloat64(float64(f))
+}
+
+func (e *jsonEncDriverGeneric) atEndOfEncode() {
+	if e.tw {
+		if e.d {
+			e.w.writen1('\n')
+		} else {
+			e.w.writen1(' ')
+		}
+	}
+}
+
+// --------------------
+
+type jsonEncDriver struct {
+	noBuiltInTypes
+	e  *Encoder
+	h  *JsonHandle
+	ew encWriter // encWriter // *encWriterSwitch
+	se extWrapper
+	// ---- cpu cache line boundary?
+	bs []byte // scratch
+	// ---- cpu cache line boundary?
+	b [jsonScratchArrayLen]byte // scratch (encode time,
+}
+
+func (e *jsonEncDriver) EncodeNil() {
+	// We always encode nil as just null (never in quotes)
+	// This allows us to easily decode if a nil in the json stream
+	// ie if initial token is n.
+	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
+
+	// if e.h.MapKeyAsString && e.c == containerMapKey {
+	// 	e.ew.writeb(jsonLiterals[jsonLitNullQ : jsonLitNullQ+6])
+	// } else {
+	// 	e.ew.writeb(jsonLiterals[jsonLitNull : jsonLitNull+4])
+	// }
+}
+
+func (e *jsonEncDriver) EncodeTime(t time.Time) {
+	// Do NOT use MarshalJSON, as it allocates internally.
+	// instead, we call AppendFormat directly, using our scratch buffer (e.b)
+	if t.IsZero() {
+		e.EncodeNil()
+	} else {
+		e.b[0] = '"'
+		b := t.AppendFormat(e.b[1:1], time.RFC3339Nano)
+		e.b[len(b)+1] = '"'
+		e.ew.writeb(e.b[:len(b)+2])
+	}
+	// v, err := t.MarshalJSON(); if err != nil { e.e.error(err) } e.ew.writeb(v)
+}
+
+func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
+	if v := ext.ConvertExt(rv); v == nil {
+		e.EncodeNil()
+	} else {
+		en.encode(v)
+	}
+}
+
+func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
+	// only encodes re.Value (never re.Data)
+	if re.Value == nil {
+		e.EncodeNil()
+	} else {
+		en.encode(re.Value)
+	}
+}
+
+func (e *jsonEncDriver) EncodeString(c charEncoding, v string) {
+	e.quoteStr(v)
+}
+
+func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	// if encoding raw bytes and RawBytesExt is configured, use it to encode
+	if v == nil {
+		e.EncodeNil()
+		return
+	}
+	if c == cRAW {
+		if e.se.InterfaceExt != nil {
+			e.EncodeExt(v, 0, &e.se, e.e)
+			return
+		}
+
+		slen := base64.StdEncoding.EncodedLen(len(v))
+		if cap(e.bs) >= slen+2 {
+			e.bs = e.bs[:slen+2]
+		} else {
+			e.bs = make([]byte, slen+2)
+		}
+		e.bs[0] = '"'
+		base64.StdEncoding.Encode(e.bs[1:], v)
+		e.bs[slen+1] = '"'
+		e.ew.writeb(e.bs)
+	} else {
+		e.quoteStr(stringView(v))
+	}
+}
+
+func (e *jsonEncDriver) EncodeAsis(v []byte) {
+	e.ew.writeb(v)
+}
+
+func (e *jsonEncDriver) quoteStr(s string) {
+	// adapted from std pkg encoding/json
+	const hex = "0123456789abcdef"
+	w := e.ew
+	htmlasis := e.h.HTMLCharsAsIs
+	w.writen1('"')
+	var start int
+	for i, slen := 0, len(s); i < slen; {
+		// encode all bytes < 0x20 (except \r, \n).
+		// also encode < > & to prevent security holes when served to some browsers.
+		if b := s[i]; b < utf8.RuneSelf {
+			// if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
+			// if (htmlasis && jsonCharSafeSet.isset(b)) || jsonCharHtmlSafeSet.isset(b) {
+			if jsonCharHtmlSafeSet.isset(b) || (htmlasis && jsonCharSafeSet.isset(b)) {
+				i++
+				continue
+			}
+			if start < i {
+				w.writestr(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				w.writen2('\\', b)
+			case '\n':
+				w.writen2('\\', 'n')
+			case '\r':
+				w.writen2('\\', 'r')
+			case '\b':
+				w.writen2('\\', 'b')
+			case '\f':
+				w.writen2('\\', 'f')
+			case '\t':
+				w.writen2('\\', 't')
+			default:
+				w.writestr(`\u00`)
+				w.writen2(hex[b>>4], hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				w.writestr(s[start:i])
+			}
+			w.writestr(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR. U+2029 is PARAGRAPH SEPARATOR.
+		// Both technically valid JSON, but bomb on JSONP, so fix here unconditionally.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				w.writestr(s[start:i])
+			}
+			w.writestr(`\u202`)
+			w.writen1(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		w.writestr(s[start:])
+	}
+	w.writen1('"')
+}
+
+type jsonDecDriver struct {
+	noBuiltInTypes
+	d  *Decoder
+	h  *JsonHandle
+	r  decReader // *decReaderSwitch // decReader
+	se extWrapper
+
+	// ---- writable fields during execution --- *try* to keep in sep cache line
+
+	c containerState
+	// tok is used to store the token read right after skipWhiteSpace.
+	tok   uint8
+	fnull bool    // found null from appendStringAsBytes
+	bs    []byte  // scratch. Initialized from b. Used for parsing strings or numbers.
+	bstr  [8]byte // scratch used for string \UXXX parsing
+	// ---- cpu cache line boundary?
+	b  [jsonScratchArrayLen]byte // scratch 1, used for parsing strings or numbers or time.Time
+	b2 [jsonScratchArrayLen]byte // scratch 2, used only for readUntil, decNumBytes
+
+	_ [3]uint64 // padding
+	// n jsonNum
+}
+
+// func jsonIsWS(b byte) bool {
+// 	// return b == ' ' || b == '\t' || b == '\r' || b == '\n'
+// 	return jsonCharWhitespaceSet.isset(b)
+// }
+
+func (d *jsonDecDriver) uncacheRead() {
+	if d.tok != 0 {
+		d.r.unreadn1()
+		d.tok = 0
+	}
+}
+
+func (d *jsonDecDriver) ReadMapStart() int {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	const xc uint8 = '{'
+	if d.tok != xc {
+		d.d.errorf("read map - expect char '%c' but got char '%c'", xc, d.tok)
+	}
+	d.tok = 0
+	d.c = containerMapStart
+	return -1
+}
+
+func (d *jsonDecDriver) ReadArrayStart() int {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	const xc uint8 = '['
+	if d.tok != xc {
+		d.d.errorf("read array - expect char '%c' but got char '%c'", xc, d.tok)
+	}
+	d.tok = 0
+	d.c = containerArrayStart
+	return -1
+}
+
+func (d *jsonDecDriver) CheckBreak() bool {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	return d.tok == '}' || d.tok == ']'
+}
+
+// For the ReadXXX methods below, we could just delegate to helper functions
+// readContainerState(c containerState, xc uint8, check bool)
+// - ReadArrayElem would become:
+//   readContainerState(containerArrayElem, ',', d.c != containerArrayStart)
+//
+// However, until mid-stack inlining comes in go1.11 which supports inlining of
+// one-liners, we explicitly write them all 5 out to elide the extra func call.
+//
+// TODO: For Go 1.11, if inlined, consider consolidating these.
+
+func (d *jsonDecDriver) ReadArrayElem() {
+	const xc uint8 = ','
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.c != containerArrayStart {
+		if d.tok != xc {
+			d.d.errorf("read array element - expect char '%c' but got char '%c'", xc, d.tok)
+		}
+		d.tok = 0
+	}
+	d.c = containerArrayElem
+}
+
+func (d *jsonDecDriver) ReadArrayEnd() {
+	const xc uint8 = ']'
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.tok != xc {
+		d.d.errorf("read array end - expect char '%c' but got char '%c'", xc, d.tok)
+	}
+	d.tok = 0
+	d.c = containerArrayEnd
+}
+
+func (d *jsonDecDriver) ReadMapElemKey() {
+	const xc uint8 = ','
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.c != containerMapStart {
+		if d.tok != xc {
+			d.d.errorf("read map key - expect char '%c' but got char '%c'", xc, d.tok)
+		}
+		d.tok = 0
+	}
+	d.c = containerMapKey
+}
+
+func (d *jsonDecDriver) ReadMapElemValue() {
+	const xc uint8 = ':'
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.tok != xc {
+		d.d.errorf("read map value - expect char '%c' but got char '%c'", xc, d.tok)
+	}
+	d.tok = 0
+	d.c = containerMapValue
+}
+
+func (d *jsonDecDriver) ReadMapEnd() {
+	const xc uint8 = '}'
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.tok != xc {
+		d.d.errorf("read map end - expect char '%c' but got char '%c'", xc, d.tok)
+	}
+	d.tok = 0
+	d.c = containerMapEnd
+}
+
+func (d *jsonDecDriver) readLit(length, fromIdx uint8) {
+	bs := d.r.readx(int(length))
+	d.tok = 0
+	if jsonValidateSymbols && !bytes.Equal(bs, jsonLiterals[fromIdx:fromIdx+length]) {
+		d.d.errorf("expecting %s: got %s", jsonLiterals[fromIdx:fromIdx+length], bs)
+		return
+	}
+}
+
+func (d *jsonDecDriver) TryDecodeAsNil() bool {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	// we shouldn't try to see if "null" was here, right?
+	// only the plain string: `null` denotes a nil (ie not quotes)
+	if d.tok == 'n' {
+		d.readLit(3, jsonLitNull+1) // (n)ull
+		return true
+	}
+	return false
+}
+
+func (d *jsonDecDriver) DecodeBool() (v bool) {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	fquot := d.c == containerMapKey && d.tok == '"'
+	if fquot {
+		d.tok = d.r.readn1()
+	}
+	switch d.tok {
+	case 'f':
+		d.readLit(4, jsonLitFalse+1) // (f)alse
+		// v = false
+	case 't':
+		d.readLit(3, jsonLitTrue+1) // (t)rue
+		v = true
+	default:
+		d.d.errorf("decode bool: got first char %c", d.tok)
+		// v = false // "unreachable"
+	}
+	if fquot {
+		d.r.readn1()
+	}
+	return
+}
+
+func (d *jsonDecDriver) DecodeTime() (t time.Time) {
+	// read string, and pass the string into json.unmarshal
+	d.appendStringAsBytes()
+	if d.fnull {
+		return
+	}
+	t, err := time.Parse(time.RFC3339, stringView(d.bs))
+	if err != nil {
+		d.d.errorv(err)
+	}
+	return
+}
+
+func (d *jsonDecDriver) ContainerType() (vt valueType) {
+	// check container type by checking the first char
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+
+	// optimize this, so we don't do 4 checks but do one computation.
+	// return jsonContainerSet[d.tok]
+
+	// ContainerType is mostly called for Map and Array,
+	// so this conditional is good enough (max 2 checks typically)
+	if b := d.tok; b == '{' {
+		return valueTypeMap
+	} else if b == '[' {
+		return valueTypeArray
+	} else if b == 'n' {
+		return valueTypeNil
+	} else if b == '"' {
+		return valueTypeString
+	}
+	return valueTypeUnset
+}
+
+func (d *jsonDecDriver) decNumBytes() (bs []byte) {
+	// stores num bytes in d.bs
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	if d.tok == '"' {
+		bs = d.r.readUntil(d.b2[:0], '"')
+		bs = bs[:len(bs)-1]
+	} else {
+		d.r.unreadn1()
+		bs = d.r.readTo(d.bs[:0], &jsonNumSet)
+	}
+	d.tok = 0
+	return bs
+}
+
+func (d *jsonDecDriver) DecodeUint64() (u uint64) {
+	bs := d.decNumBytes()
+	n, neg, badsyntax, overflow := jsonParseInteger(bs)
+	if overflow {
+		d.d.errorf("overflow parsing unsigned integer: %s", bs)
+	} else if neg {
+		d.d.errorf("minus found parsing unsigned integer: %s", bs)
+	} else if badsyntax {
+		// fallback: try to decode as float, and cast
+		n = d.decUint64ViaFloat(stringView(bs))
+	}
+	return n
+}
+
+func (d *jsonDecDriver) DecodeInt64() (i int64) {
+	const cutoff = uint64(1 << uint(64-1))
+	bs := d.decNumBytes()
+	n, neg, badsyntax, overflow := jsonParseInteger(bs)
+	if overflow {
+		d.d.errorf("overflow parsing integer: %s", bs)
+	} else if badsyntax {
+		// d.d.errorf("invalid syntax for integer: %s", bs)
+		// fallback: try to decode as float, and cast
+		if neg {
+			n = d.decUint64ViaFloat(stringView(bs[1:]))
+		} else {
+			n = d.decUint64ViaFloat(stringView(bs))
+		}
+	}
+	if neg {
+		if n > cutoff {
+			d.d.errorf("overflow parsing integer: %s", bs)
+		}
+		i = -(int64(n))
+	} else {
+		if n >= cutoff {
+			d.d.errorf("overflow parsing integer: %s", bs)
+		}
+		i = int64(n)
+	}
+	return
+}
+
+func (d *jsonDecDriver) decUint64ViaFloat(s string) (u uint64) {
+	f, err := strconv.ParseFloat(s, 64)
+	if err != nil {
+		d.d.errorf("invalid syntax for integer: %s", s)
+		// d.d.errorv(err)
+	}
+	fi, ff := math.Modf(f)
+	if ff > 0 {
+		d.d.errorf("fractional part found parsing integer: %s", s)
+	} else if fi > float64(math.MaxUint64) {
+		d.d.errorf("overflow parsing integer: %s", s)
+	}
+	return uint64(fi)
+}
+
+func (d *jsonDecDriver) DecodeFloat64() (f float64) {
+	bs := d.decNumBytes()
+	f, err := strconv.ParseFloat(stringView(bs), 64)
+	if err != nil {
+		d.d.errorv(err)
+	}
+	return
+}
+
+func (d *jsonDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
+	if ext == nil {
+		re := rv.(*RawExt)
+		re.Tag = xtag
+		d.d.decode(&re.Value)
+	} else {
+		var v interface{}
+		d.d.decode(&v)
+		ext.UpdateExt(rv, v)
+	}
+	return
+}
+
+func (d *jsonDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+	// if decoding into raw bytes, and the RawBytesExt is configured, use it to decode.
+	if d.se.InterfaceExt != nil {
+		bsOut = bs
+		d.DecodeExt(&bsOut, 0, &d.se)
+		return
+	}
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
+	if d.tok == '[' {
+		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
+		return
+	}
+	d.appendStringAsBytes()
+	// base64 encodes []byte{} as "", and we encode nil []byte as null.
+	// Consequently, base64 should decode null as a nil []byte, and "" as an empty []byte{}.
+	// appendStringAsBytes returns a zero-len slice for both, so as not to reset d.bs.
+	// However, it sets a fnull field to true, so we can check if a null was found.
+	if len(d.bs) == 0 {
+		if d.fnull {
+			return nil
+		}
+		return []byte{}
+	}
+	bs0 := d.bs
+	slen := base64.StdEncoding.DecodedLen(len(bs0))
+	if slen <= cap(bs) {
+		bsOut = bs[:slen]
+	} else if zerocopy && slen <= cap(d.b2) {
+		bsOut = d.b2[:slen]
+	} else {
+		bsOut = make([]byte, slen)
+	}
+	slen2, err := base64.StdEncoding.Decode(bsOut, bs0)
+	if err != nil {
+		d.d.errorf("error decoding base64 binary '%s': %v", bs0, err)
+		return nil
+	}
+	if slen != slen2 {
+		bsOut = bsOut[:slen2]
+	}
+	return
+}
+
+func (d *jsonDecDriver) DecodeString() (s string) {
+	d.appendStringAsBytes()
+	return d.bsToString()
+}
+
+func (d *jsonDecDriver) DecodeStringAsBytes() (s []byte) {
+	d.appendStringAsBytes()
+	return d.bs
+}
+
+func (d *jsonDecDriver) appendStringAsBytes() {
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+
+	d.fnull = false
+	if d.tok != '"' {
+		// d.d.errorf("expect char '%c' but got char '%c'", '"', d.tok)
+		// handle non-string scalar: null, true, false or a number
+		switch d.tok {
+		case 'n':
+			d.readLit(3, jsonLitNull+1) // (n)ull
+			d.bs = d.bs[:0]
+			d.fnull = true
+		case 'f':
+			d.readLit(4, jsonLitFalse+1) // (f)alse
+			d.bs = d.bs[:5]
+			copy(d.bs, "false")
+		case 't':
+			d.readLit(3, jsonLitTrue+1) // (t)rue
+			d.bs = d.bs[:4]
+			copy(d.bs, "true")
+		default:
+			// try to parse a valid number
+			bs := d.decNumBytes()
+			if len(bs) <= cap(d.bs) {
+				d.bs = d.bs[:len(bs)]
+			} else {
+				d.bs = make([]byte, len(bs))
+			}
+			copy(d.bs, bs)
+		}
+		return
+	}
+
+	d.tok = 0
+	r := d.r
+	var cs = r.readUntil(d.b2[:0], '"')
+	var cslen = len(cs)
+	var c uint8
+	v := d.bs[:0]
+	// append on each byte seen can be expensive, so we just
+	// keep track of where we last read a contiguous set of
+	// non-special bytes (using cursor variable),
+	// and when we see a special byte
+	// e.g. end-of-slice, " or \,
+	// we will append the full range into the v slice before proceeding
+	for i, cursor := 0, 0; ; {
+		if i == cslen {
+			v = append(v, cs[cursor:]...)
+			cs = r.readUntil(d.b2[:0], '"')
+			cslen = len(cs)
+			i, cursor = 0, 0
+		}
+		c = cs[i]
+		if c == '"' {
+			v = append(v, cs[cursor:i]...)
+			break
+		}
+		if c != '\\' {
+			i++
+			continue
+		}
+		v = append(v, cs[cursor:i]...)
+		i++
+		c = cs[i]
+		switch c {
+		case '"', '\\', '/', '\'':
+			v = append(v, c)
+		case 'b':
+			v = append(v, '\b')
+		case 'f':
+			v = append(v, '\f')
+		case 'n':
+			v = append(v, '\n')
+		case 'r':
+			v = append(v, '\r')
+		case 't':
+			v = append(v, '\t')
+		case 'u':
+			var r rune
+			var rr uint32
+			if len(cs) < i+4 { // may help reduce bounds-checking
+				d.d.errorf("need at least 4 more bytes for unicode sequence")
+			}
+			// c = cs[i+4] // may help reduce bounds-checking
+			for j := 1; j < 5; j++ {
+				// best to use explicit if-else
+				// - not a table, etc which involve memory loads, array lookup with bounds checks, etc
+				c = cs[i+j]
+				if c >= '0' && c <= '9' {
+					rr = rr*16 + uint32(c-jsonU4Chk2)
+				} else if c >= 'a' && c <= 'f' {
+					rr = rr*16 + uint32(c-jsonU4Chk1)
+				} else if c >= 'A' && c <= 'F' {
+					rr = rr*16 + uint32(c-jsonU4Chk0)
+				} else {
+					r = unicode.ReplacementChar
+					i += 4
+					goto encode_rune
+				}
+			}
+			r = rune(rr)
+			i += 4
+			if utf16.IsSurrogate(r) {
+				if len(cs) >= i+6 && cs[i+2] == 'u' && cs[i+1] == '\\' {
+					i += 2
+					// c = cs[i+4] // may help reduce bounds-checking
+					var rr1 uint32
+					for j := 1; j < 5; j++ {
+						c = cs[i+j]
+						if c >= '0' && c <= '9' {
+							rr = rr*16 + uint32(c-jsonU4Chk2)
+						} else if c >= 'a' && c <= 'f' {
+							rr = rr*16 + uint32(c-jsonU4Chk1)
+						} else if c >= 'A' && c <= 'F' {
+							rr = rr*16 + uint32(c-jsonU4Chk0)
+						} else {
+							r = unicode.ReplacementChar
+							i += 4
+							goto encode_rune
+						}
+					}
+					r = utf16.DecodeRune(r, rune(rr1))
+					i += 4
+				} else {
+					r = unicode.ReplacementChar
+					goto encode_rune
+				}
+			}
+		encode_rune:
+			w2 := utf8.EncodeRune(d.bstr[:], r)
+			v = append(v, d.bstr[:w2]...)
+		default:
+			d.d.errorf("unsupported escaped value: %c", c)
+		}
+		i++
+		cursor = i
+	}
+	d.bs = v
+}
+
+func (d *jsonDecDriver) nakedNum(z *decNaked, bs []byte) (err error) {
+	const cutoff = uint64(1 << uint(64-1))
+	var n uint64
+	var neg, badsyntax, overflow bool
+
+	if d.h.PreferFloat {
+		goto F
+	}
+	n, neg, badsyntax, overflow = jsonParseInteger(bs)
+	if badsyntax || overflow {
+		goto F
+	}
+	if neg {
+		if n > cutoff {
+			goto F
+		}
+		z.v = valueTypeInt
+		z.i = -(int64(n))
+	} else if d.h.SignedInteger {
+		if n >= cutoff {
+			goto F
+		}
+		z.v = valueTypeInt
+		z.i = int64(n)
+	} else {
+		z.v = valueTypeUint
+		z.u = n
+	}
+	return
+F:
+	z.v = valueTypeFloat
+	z.f, err = strconv.ParseFloat(stringView(bs), 64)
+	return
+}
+
+func (d *jsonDecDriver) bsToString() string {
+	// if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key
+	if jsonAlwaysReturnInternString || d.c == containerMapKey {
+		return d.d.string(d.bs)
+	}
+	return string(d.bs)
+}
+
+func (d *jsonDecDriver) DecodeNaked() {
+	z := d.d.n
+	// var decodeFurther bool
+
+	if d.tok == 0 {
+		d.tok = d.r.skip(&jsonCharWhitespaceSet)
+	}
+	switch d.tok {
+	case 'n':
+		d.readLit(3, jsonLitNull+1) // (n)ull
+		z.v = valueTypeNil
+	case 'f':
+		d.readLit(4, jsonLitFalse+1) // (f)alse
+		z.v = valueTypeBool
+		z.b = false
+	case 't':
+		d.readLit(3, jsonLitTrue+1) // (t)rue
+		z.v = valueTypeBool
+		z.b = true
+	case '{':
+		z.v = valueTypeMap // don't consume. kInterfaceNaked will call ReadMapStart
+	case '[':
+		z.v = valueTypeArray // don't consume. kInterfaceNaked will call ReadArrayStart
+	case '"':
+		// if a string, and MapKeyAsString, then try to decode it as a nil, bool or number first
+		d.appendStringAsBytes()
+		if len(d.bs) > 0 && d.c == containerMapKey && d.h.MapKeyAsString {
+			switch stringView(d.bs) {
+			case "null":
+				z.v = valueTypeNil
+			case "true":
+				z.v = valueTypeBool
+				z.b = true
+			case "false":
+				z.v = valueTypeBool
+				z.b = false
+			default:
+				// check if a number: float, int or uint
+				if err := d.nakedNum(z, d.bs); err != nil {
+					z.v = valueTypeString
+					z.s = d.bsToString()
+				}
+			}
+		} else {
+			z.v = valueTypeString
+			z.s = d.bsToString()
+		}
+	default: // number
+		bs := d.decNumBytes()
+		if len(bs) == 0 {
+			d.d.errorf("decode number from empty string")
+			return
+		}
+		if err := d.nakedNum(z, bs); err != nil {
+			d.d.errorf("decode number from %s: %v", bs, err)
+			return
+		}
+	}
+	// if decodeFurther {
+	// 	d.s.sc.retryRead()
+	// }
+	return
+}
+
+//----------------------
+
+// JsonHandle is a handle for JSON encoding format.
+//
+// Json is comprehensively supported:
+//    - decodes numbers into interface{} as int, uint or float64
+//      based on how the number looks and some config parameters e.g. PreferFloat, SignedInt, etc.
+//    - decode integers from float formatted numbers e.g. 1.27e+8
+//    - decode any json value (numbers, bool, etc) from quoted strings
+//    - configurable way to encode/decode []byte .
+//      by default, encodes and decodes []byte using base64 Std Encoding
+//    - UTF-8 support for encoding and decoding
+//
+// It has better performance than the json library in the standard library,
+// by leveraging the performance improvements of the codec library.
+//
+// In addition, it doesn't read more bytes than necessary during a decode, which allows
+// reading multiple values from a stream containing json and non-json content.
+// For example, a user can read a json value, then a cbor value, then a msgpack value,
+// all from the same stream in sequence.
+//
+// Note that, when decoding quoted strings, invalid UTF-8 or invalid UTF-16 surrogate pairs are
+// not treated as an error. Instead, they are replaced by the Unicode replacement character U+FFFD.
+type JsonHandle struct {
+	textEncodingType
+	BasicHandle
+
+	// Indent indicates how a value is encoded.
+	//   - If positive, indent by that number of spaces.
+	//   - If negative, indent by that number of tabs.
+	Indent int8
+
+	// IntegerAsString controls how integers (signed and unsigned) are encoded.
+	//
+	// Per the JSON Spec, JSON numbers are 64-bit floating point numbers.
+	// Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision.
+	// This can be mitigated by configuring how to encode integers.
+	//
+	// IntegerAsString interpretes the following values:
+	//   - if 'L', then encode integers > 2^53 as a json string.
+	//   - if 'A', then encode all integers as a json string
+	//             containing the exact integer representation as a decimal.
+	//   - else    encode all integers as a json number (default)
+	IntegerAsString byte
+
+	// HTMLCharsAsIs controls how to encode some special characters to html: < > &
+	//
+	// By default, we encode them as \uXXX
+	// to prevent security holes when served from some browsers.
+	HTMLCharsAsIs bool
+
+	// PreferFloat says that we will default to decoding a number as a float.
+	// If not set, we will examine the characters of the number and decode as an
+	// integer type if it doesn't have any of the characters [.eE].
+	PreferFloat bool
+
+	// TermWhitespace says that we add a whitespace character
+	// at the end of an encoding.
+	//
+	// The whitespace is important, especially if using numbers in a context
+	// where multiple items are written to a stream.
+	TermWhitespace bool
+
+	// MapKeyAsString says to encode all map keys as strings.
+	//
+	// Use this to enforce strict json output.
+	// The only caveat is that nil value is ALWAYS written as null (never as "null")
+	MapKeyAsString bool
+
+	// _ [2]byte // padding
+
+	// Note: below, we store hardly-used items e.g. RawBytesExt is cached in the (en|de)cDriver.
+
+	// RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way.
+	// If not configured, raw bytes are encoded to/from base64 text.
+	RawBytesExt InterfaceExt
+
+	_ [2]uint64 // padding
+}
+
+// Name returns the name of the handle: json
+func (h *JsonHandle) Name() string            { return "json" }
+func (h *JsonHandle) hasElemSeparators() bool { return true }
+func (h *JsonHandle) typical() bool {
+	return h.Indent == 0 && !h.MapKeyAsString && h.IntegerAsString != 'A' && h.IntegerAsString != 'L'
+}
+
+type jsonTypical interface {
+	typical()
+}
+
+func (h *JsonHandle) recreateEncDriver(ed encDriver) (v bool) {
+	_, v = ed.(jsonTypical)
+	return v != h.typical()
+}
+
+// SetInterfaceExt sets an extension
+func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
+}
+
+type jsonEncDriverTypicalImpl struct {
+	jsonEncDriver
+	jsonEncDriverTypical
+	_ [1]uint64 // padding
+}
+
+func (x *jsonEncDriverTypicalImpl) reset() {
+	x.jsonEncDriver.reset()
+	x.jsonEncDriverTypical.reset(&x.jsonEncDriver)
+}
+
+type jsonEncDriverGenericImpl struct {
+	jsonEncDriver
+	jsonEncDriverGeneric
+}
+
+func (x *jsonEncDriverGenericImpl) reset() {
+	x.jsonEncDriver.reset()
+	x.jsonEncDriverGeneric.reset(&x.jsonEncDriver)
+}
+
+func (h *JsonHandle) newEncDriver(e *Encoder) (ee encDriver) {
+	var hd *jsonEncDriver
+	if h.typical() {
+		var v jsonEncDriverTypicalImpl
+		ee = &v
+		hd = &v.jsonEncDriver
+	} else {
+		var v jsonEncDriverGenericImpl
+		ee = &v
+		hd = &v.jsonEncDriver
+	}
+	hd.e, hd.h, hd.bs = e, h, hd.b[:0]
+	hd.se.BytesExt = bytesExtFailer{}
+	ee.reset()
+	return
+}
+
+func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
+	// d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
+	hd := jsonDecDriver{d: d, h: h}
+	hd.se.BytesExt = bytesExtFailer{}
+	hd.bs = hd.b[:0]
+	hd.reset()
+	return &hd
+}
+
+func (e *jsonEncDriver) reset() {
+	e.ew = e.e.w // e.e.w // &e.e.encWriterSwitch
+	e.se.InterfaceExt = e.h.RawBytesExt
+	if e.bs != nil {
+		e.bs = e.bs[:0]
+	}
+}
+
+func (d *jsonDecDriver) reset() {
+	d.r = d.d.r // &d.d.decReaderSwitch // d.d.r
+	d.se.InterfaceExt = d.h.RawBytesExt
+	if d.bs != nil {
+		d.bs = d.bs[:0]
+	}
+	d.c, d.tok = 0, 0
+	// d.n.reset()
+}
+
+func jsonFloatStrconvFmtPrec(f float64) (fmt byte, prec int) {
+	prec = -1
+	var abs = math.Abs(f)
+	if abs != 0 && (abs < 1e-6 || abs >= 1e21) {
+		fmt = 'e'
+	} else {
+		fmt = 'f'
+		// set prec to 1 iff mod is 0.
+		//     better than using jsonIsFloatBytesB2 to check if a . or E in the float bytes.
+		// this ensures that every float has an e or .0 in it.
+		if abs <= 1 {
+			if abs == 0 || abs == 1 {
+				prec = 1
+			}
+		} else if _, mod := math.Modf(abs); mod == 0 {
+			prec = 1
+		}
+	}
+	return
+}
+
+// custom-fitted version of strconv.Parse(Ui|I)nt.
+// Also ensures we don't have to search for .eE to determine if a float or not.
+func jsonParseInteger(s []byte) (n uint64, neg, badSyntax, overflow bool) {
+	const maxUint64 = (1<<64 - 1)
+	const cutoff = maxUint64/10 + 1
+
+	if len(s) == 0 {
+		badSyntax = true
+		return
+	}
+	switch s[0] {
+	case '+':
+		s = s[1:]
+	case '-':
+		s = s[1:]
+		neg = true
+	}
+	for _, c := range s {
+		if c < '0' || c > '9' {
+			badSyntax = true
+			return
+		}
+		// unsigned integers don't overflow well on multiplication, so check cutoff here
+		// e.g. (maxUint64-5)*10 doesn't overflow well ...
+		if n >= cutoff {
+			overflow = true
+			return
+		}
+		n *= 10
+		n1 := n + uint64(c-'0')
+		if n1 < n || n1 > maxUint64 {
+			overflow = true
+			return
+		}
+		n = n1
+	}
+	return
+}
+
+var _ decDriver = (*jsonDecDriver)(nil)
+var _ encDriver = (*jsonEncDriverGenericImpl)(nil)
+var _ encDriver = (*jsonEncDriverTypicalImpl)(nil)
+var _ jsonTypical = (*jsonEncDriverTypical)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl b/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
new file mode 100644
index 0000000..90d758c
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
@@ -0,0 +1,154 @@
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from mammoth-test.go.tmpl - DO NOT EDIT.
+
+package codec
+
+import "testing"
+import "fmt"
+import "reflect"
+
+// TestMammoth has all the different paths optimized in fast-path
+// It has all the primitives, slices and maps.
+// 
+// For each of those types, it has a pointer and a non-pointer field.
+
+func init() { _ = fmt.Printf } // so we can include fmt as needed
+
+type TestMammoth struct {
+
+{{range .Values }}{{if .Primitive }}{{/*
+*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
+{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
+{{end}}{{end}}
+
+{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
+*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
+{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
+{{end}}{{end}}{{end}}
+
+{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
+*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
+{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
+{{end}}{{end}}{{end}}
+
+}
+
+{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
+*/}} type {{ .MethodNamePfx "typMbs" false }} []{{ .Elem }}
+func (_ {{ .MethodNamePfx "typMbs" false }}) MapBySlice() { }
+{{end}}{{end}}{{end}}
+
+{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
+*/}} type {{ .MethodNamePfx "typMap" false }} map[{{ .MapKey }}]{{ .Elem }}
+{{end}}{{end}}{{end}}
+
+func doTestMammothSlices(t *testing.T, h Handle) {
+{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
+*/}}
+    var v{{$i}}va [8]{{ .Elem }}
+    for _, v := range [][]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .Elem }}, {{ zerocmd .Elem }}, {{ zerocmd .Elem }}, {{ nonzerocmd .Elem }} } } { {{/*
+    // fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
+    //   - encode value to some []byte
+    //   - decode into a length-wise-equal []byte
+    //   - check if equal to initial slice
+    //   - encode ptr to the value
+    //   - check if encode bytes are same
+    //   - decode into ptrs to: nil, then 1-elem slice, equal-length, then large len slice
+    //   - decode into non-addressable slice of equal length, then larger len 
+    //   - for each decode, compare elem-by-elem to the original slice
+    //   - 
+    //   - rinse and repeat for a MapBySlice version
+    //   - 
+    */}}
+    var v{{$i}}v1, v{{$i}}v2 []{{ .Elem }}
+	v{{$i}}v1 = v
+	bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
+	testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
+	testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-noaddr")
+	// ...
+	bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
+	v{{$i}}v2 = nil
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
+	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
+	v{{$i}}v2 = v{{$i}}va[:1:1]
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-1")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-1")
+	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
+	v{{$i}}v2 = v{{$i}}va[:len(v{{$i}}v1):len(v{{$i}}v1)]
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-len")
+	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
+	v{{$i}}v2 = v{{$i}}va[:]
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-cap")
+	if len(v{{$i}}v1) > 1 {
+	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
+	testUnmarshalErr((&v{{$i}}va)[:len(v{{$i}}v1)], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len-noaddr")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-len-noaddr")
+	v{{$i}}va = [8]{{ .Elem }}{} // clear the array
+	testUnmarshalErr((&v{{$i}}va)[:], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap-noaddr")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-cap-noaddr")
+    }
+    // ...
+    var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMbs" false }}
+	v{{$i}}v2 = nil
+    if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
+    v{{$i}}v3 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v1)
+    v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
+    bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
+    testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
+    testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
+    bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
+    v{{$i}}v2 = nil
+    v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
+    testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
+    testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
+    }
+{{end}}{{end}}{{end}}
+}
+
+func doTestMammothMaps(t *testing.T, h Handle) {
+{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
+*/}}
+    for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .MapKey }}:{{ zerocmd .Elem }} {{if ne "bool" .MapKey}}, {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} {{end}} } } {
+    // fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
+    var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
+	v{{$i}}v1 = v
+	bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
+	testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
+	testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-map-v{{$i}}-noaddr") // decode into non-addressable map value
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-noaddr")
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-len")
+	bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
+	v{{$i}}v2 = nil
+	testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-nil")
+	testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-nil")
+    // ...
+	if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
+    var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMap" false }}
+	v{{$i}}v3 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v1)
+	v{{$i}}v4 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v2)
+    bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-map-v{{$i}}-custom")
+	testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
+	testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-map-v{{$i}}-p-len")
+    }
+{{end}}{{end}}{{end}}
+
+}
+
+func doTestMammothMapsAndSlices(t *testing.T, h Handle) {
+     doTestMammothSlices(t, h)
+     doTestMammothMaps(t, h)
+}
diff --git a/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl b/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
new file mode 100644
index 0000000..7cdf8f5
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
@@ -0,0 +1,94 @@
+// +build !notfastpath
+
+// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
+
+package codec
+
+// Increase codecoverage by covering all the codecgen paths, in fast-path and gen-helper.go....
+//
+// Add:
+// - test file for creating a mammoth generated file as _mammoth_generated.go
+//   - generate a second mammoth files in a different file: mammoth2_generated_test.go
+//     - mammoth-test.go.tmpl will do this
+//   - run codecgen on it, into mammoth2_codecgen_generated_test.go (no build tags)
+//   - as part of TestMammoth, run it also
+//   - this will cover all the codecgen, gen-helper, etc in one full run
+//   - check in mammoth* files into github also
+// - then
+//
+// Now, add some types:
+//  - some that implement BinaryMarshal, TextMarshal, JSONMarshal, and one that implements none of it
+//  - create a wrapper type that includes TestMammoth2, with it in slices, and maps, and the custom types
+//  - this wrapper object is what we work encode/decode (so that the codecgen methods are called)
+
+
+// import "encoding/binary"
+import "fmt"
+
+type TestMammoth2 struct {
+
+{{range .Values }}{{if .Primitive }}{{/*
+*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
+{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
+{{end}}{{end}}
+
+{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
+*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
+{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
+{{end}}{{end}}{{end}}
+
+{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
+*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
+{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
+{{end}}{{end}}{{end}}
+
+}
+
+// -----------
+
+type testMammoth2Binary uint64
+func (x testMammoth2Binary) MarshalBinary() (data []byte, err error) {
+data = make([]byte, 8)
+bigen.PutUint64(data, uint64(x))
+return
+}
+func (x *testMammoth2Binary) UnmarshalBinary(data []byte) (err error) {
+*x = testMammoth2Binary(bigen.Uint64(data))
+return
+}
+
+type testMammoth2Text uint64
+func (x testMammoth2Text) MarshalText() (data []byte, err error) {
+data = []byte(fmt.Sprintf("%b", uint64(x)))
+return
+}
+func (x *testMammoth2Text) UnmarshalText(data []byte) (err error) {
+_, err = fmt.Sscanf(string(data), "%b", (*uint64)(x))
+return
+}
+
+type testMammoth2Json uint64
+func (x testMammoth2Json) MarshalJSON() (data []byte, err error) {
+data = []byte(fmt.Sprintf("%v", uint64(x)))
+return
+}
+func (x *testMammoth2Json) UnmarshalJSON(data []byte) (err error) {
+_, err = fmt.Sscanf(string(data), "%v", (*uint64)(x))
+return
+}
+
+type testMammoth2Basic [4]uint64
+
+type TestMammoth2Wrapper struct {
+  V TestMammoth2
+  T testMammoth2Text
+  B testMammoth2Binary
+  J testMammoth2Json
+  C testMammoth2Basic
+  M map[testMammoth2Basic]TestMammoth2
+  L []TestMammoth2
+  A [4]int64
+}
diff --git a/vendor/github.com/ugorji/go/codec/msgpack.go b/vendor/github.com/ugorji/go/codec/msgpack.go
new file mode 100644
index 0000000..3271579
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/msgpack.go
@@ -0,0 +1,1092 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+/*
+MSGPACK
+
+Msgpack-c implementation powers the c, c++, python, ruby, etc libraries.
+We need to maintain compatibility with it and how it encodes integer values
+without caring about the type.
+
+For compatibility with behaviour of msgpack-c reference implementation:
+  - Go intX (>0) and uintX
+       IS ENCODED AS
+    msgpack +ve fixnum, unsigned
+  - Go intX (<0)
+       IS ENCODED AS
+    msgpack -ve fixnum, signed
+*/
+
+package codec
+
+import (
+	"fmt"
+	"io"
+	"math"
+	"net/rpc"
+	"reflect"
+	"time"
+)
+
+const (
+	mpPosFixNumMin byte = 0x00
+	mpPosFixNumMax      = 0x7f
+	mpFixMapMin         = 0x80
+	mpFixMapMax         = 0x8f
+	mpFixArrayMin       = 0x90
+	mpFixArrayMax       = 0x9f
+	mpFixStrMin         = 0xa0
+	mpFixStrMax         = 0xbf
+	mpNil               = 0xc0
+	_                   = 0xc1
+	mpFalse             = 0xc2
+	mpTrue              = 0xc3
+	mpFloat             = 0xca
+	mpDouble            = 0xcb
+	mpUint8             = 0xcc
+	mpUint16            = 0xcd
+	mpUint32            = 0xce
+	mpUint64            = 0xcf
+	mpInt8              = 0xd0
+	mpInt16             = 0xd1
+	mpInt32             = 0xd2
+	mpInt64             = 0xd3
+
+	// extensions below
+	mpBin8     = 0xc4
+	mpBin16    = 0xc5
+	mpBin32    = 0xc6
+	mpExt8     = 0xc7
+	mpExt16    = 0xc8
+	mpExt32    = 0xc9
+	mpFixExt1  = 0xd4
+	mpFixExt2  = 0xd5
+	mpFixExt4  = 0xd6
+	mpFixExt8  = 0xd7
+	mpFixExt16 = 0xd8
+
+	mpStr8  = 0xd9 // new
+	mpStr16 = 0xda
+	mpStr32 = 0xdb
+
+	mpArray16 = 0xdc
+	mpArray32 = 0xdd
+
+	mpMap16 = 0xde
+	mpMap32 = 0xdf
+
+	mpNegFixNumMin = 0xe0
+	mpNegFixNumMax = 0xff
+)
+
+var mpTimeExtTag int8 = -1
+var mpTimeExtTagU = uint8(mpTimeExtTag)
+
+// var mpdesc = map[byte]string{
+// 	mpPosFixNumMin: "PosFixNumMin",
+// 	mpPosFixNumMax: "PosFixNumMax",
+// 	mpFixMapMin:    "FixMapMin",
+// 	mpFixMapMax:    "FixMapMax",
+// 	mpFixArrayMin:  "FixArrayMin",
+// 	mpFixArrayMax:  "FixArrayMax",
+// 	mpFixStrMin:    "FixStrMin",
+// 	mpFixStrMax:    "FixStrMax",
+// 	mpNil:          "Nil",
+// 	mpFalse:        "False",
+// 	mpTrue:         "True",
+// 	mpFloat:        "Float",
+// 	mpDouble:       "Double",
+// 	mpUint8:        "Uint8",
+// 	mpUint16:       "Uint16",
+// 	mpUint32:       "Uint32",
+// 	mpUint64:       "Uint64",
+// 	mpInt8:         "Int8",
+// 	mpInt16:        "Int16",
+// 	mpInt32:        "Int32",
+// 	mpInt64:        "Int64",
+// 	mpBin8:         "Bin8",
+// 	mpBin16:        "Bin16",
+// 	mpBin32:        "Bin32",
+// 	mpExt8:         "Ext8",
+// 	mpExt16:        "Ext16",
+// 	mpExt32:        "Ext32",
+// 	mpFixExt1:      "FixExt1",
+// 	mpFixExt2:      "FixExt2",
+// 	mpFixExt4:      "FixExt4",
+// 	mpFixExt8:      "FixExt8",
+// 	mpFixExt16:     "FixExt16",
+// 	mpStr8:         "Str8",
+// 	mpStr16:        "Str16",
+// 	mpStr32:        "Str32",
+// 	mpArray16:      "Array16",
+// 	mpArray32:      "Array32",
+// 	mpMap16:        "Map16",
+// 	mpMap32:        "Map32",
+// 	mpNegFixNumMin: "NegFixNumMin",
+// 	mpNegFixNumMax: "NegFixNumMax",
+// }
+
+func mpdesc(bd byte) string {
+	switch bd {
+	case mpNil:
+		return "nil"
+	case mpFalse:
+		return "false"
+	case mpTrue:
+		return "true"
+	case mpFloat, mpDouble:
+		return "float"
+	case mpUint8, mpUint16, mpUint32, mpUint64:
+		return "uint"
+	case mpInt8, mpInt16, mpInt32, mpInt64:
+		return "int"
+	default:
+		switch {
+		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
+			return "int"
+		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
+			return "int"
+		case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax:
+			return "string|bytes"
+		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
+			return "bytes"
+		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
+			return "array"
+		case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax:
+			return "map"
+		case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32:
+			return "ext"
+		default:
+			return "unknown"
+		}
+	}
+}
+
+// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
+// that the backend RPC service takes multiple arguments, which have been arranged
+// in sequence in the slice.
+//
+// The Codec then passes it AS-IS to the rpc service (without wrapping it in an
+// array of 1 element).
+type MsgpackSpecRpcMultiArgs []interface{}
+
+// A MsgpackContainer type specifies the different types of msgpackContainers.
+type msgpackContainerType struct {
+	fixCutoff                   int
+	bFixMin, b8, b16, b32       byte
+	hasFixMin, has8, has8Always bool
+}
+
+var (
+	msgpackContainerStr = msgpackContainerType{
+		32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false,
+	}
+	msgpackContainerBin = msgpackContainerType{
+		0, 0, mpBin8, mpBin16, mpBin32, false, true, true,
+	}
+	msgpackContainerList = msgpackContainerType{
+		16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false,
+	}
+	msgpackContainerMap = msgpackContainerType{
+		16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false,
+	}
+)
+
+//---------------------------------------------
+
+type msgpackEncDriver struct {
+	noBuiltInTypes
+	encDriverNoopContainerWriter
+	// encNoSeparator
+	e *Encoder
+	w encWriter
+	h *MsgpackHandle
+	x [8]byte
+	_ [3]uint64 // padding
+}
+
+func (e *msgpackEncDriver) EncodeNil() {
+	e.w.writen1(mpNil)
+}
+
+func (e *msgpackEncDriver) EncodeInt(i int64) {
+	// if i >= 0 {
+	// 	e.EncodeUint(uint64(i))
+	// } else if false &&
+	if i > math.MaxInt8 {
+		if i <= math.MaxInt16 {
+			e.w.writen1(mpInt16)
+			bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
+		} else if i <= math.MaxInt32 {
+			e.w.writen1(mpInt32)
+			bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
+		} else {
+			e.w.writen1(mpInt64)
+			bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
+		}
+	} else if i >= -32 {
+		if e.h.NoFixedNum {
+			e.w.writen2(mpInt8, byte(i))
+		} else {
+			e.w.writen1(byte(i))
+		}
+	} else if i >= math.MinInt8 {
+		e.w.writen2(mpInt8, byte(i))
+	} else if i >= math.MinInt16 {
+		e.w.writen1(mpInt16)
+		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
+	} else if i >= math.MinInt32 {
+		e.w.writen1(mpInt32)
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
+	} else {
+		e.w.writen1(mpInt64)
+		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
+	}
+}
+
+func (e *msgpackEncDriver) EncodeUint(i uint64) {
+	if i <= math.MaxInt8 {
+		if e.h.NoFixedNum {
+			e.w.writen2(mpUint8, byte(i))
+		} else {
+			e.w.writen1(byte(i))
+		}
+	} else if i <= math.MaxUint8 {
+		e.w.writen2(mpUint8, byte(i))
+	} else if i <= math.MaxUint16 {
+		e.w.writen1(mpUint16)
+		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i))
+	} else if i <= math.MaxUint32 {
+		e.w.writen1(mpUint32)
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i))
+	} else {
+		e.w.writen1(mpUint64)
+		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i))
+	}
+}
+
+func (e *msgpackEncDriver) EncodeBool(b bool) {
+	if b {
+		e.w.writen1(mpTrue)
+	} else {
+		e.w.writen1(mpFalse)
+	}
+}
+
+func (e *msgpackEncDriver) EncodeFloat32(f float32) {
+	e.w.writen1(mpFloat)
+	bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
+}
+
+func (e *msgpackEncDriver) EncodeFloat64(f float64) {
+	e.w.writen1(mpDouble)
+	bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
+}
+
+func (e *msgpackEncDriver) EncodeTime(t time.Time) {
+	if t.IsZero() {
+		e.EncodeNil()
+		return
+	}
+	t = t.UTC()
+	sec, nsec := t.Unix(), uint64(t.Nanosecond())
+	var data64 uint64
+	var l = 4
+	if sec >= 0 && sec>>34 == 0 {
+		data64 = (nsec << 34) | uint64(sec)
+		if data64&0xffffffff00000000 != 0 {
+			l = 8
+		}
+	} else {
+		l = 12
+	}
+	if e.h.WriteExt {
+		e.encodeExtPreamble(mpTimeExtTagU, l)
+	} else {
+		e.writeContainerLen(msgpackContainerStr, l)
+	}
+	switch l {
+	case 4:
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64))
+	case 8:
+		bigenHelper{e.x[:8], e.w}.writeUint64(data64)
+	case 12:
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec))
+		bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec))
+	}
+}
+
+func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
+	bs := ext.WriteExt(v)
+	if bs == nil {
+		e.EncodeNil()
+		return
+	}
+	if e.h.WriteExt {
+		e.encodeExtPreamble(uint8(xtag), len(bs))
+		e.w.writeb(bs)
+	} else {
+		e.EncodeStringBytes(cRAW, bs)
+	}
+}
+
+func (e *msgpackEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
+	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
+	e.w.writeb(re.Data)
+}
+
+func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) {
+	if l == 1 {
+		e.w.writen2(mpFixExt1, xtag)
+	} else if l == 2 {
+		e.w.writen2(mpFixExt2, xtag)
+	} else if l == 4 {
+		e.w.writen2(mpFixExt4, xtag)
+	} else if l == 8 {
+		e.w.writen2(mpFixExt8, xtag)
+	} else if l == 16 {
+		e.w.writen2(mpFixExt16, xtag)
+	} else if l < 256 {
+		e.w.writen2(mpExt8, byte(l))
+		e.w.writen1(xtag)
+	} else if l < 65536 {
+		e.w.writen1(mpExt16)
+		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l))
+		e.w.writen1(xtag)
+	} else {
+		e.w.writen1(mpExt32)
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l))
+		e.w.writen1(xtag)
+	}
+}
+
+func (e *msgpackEncDriver) WriteArrayStart(length int) {
+	e.writeContainerLen(msgpackContainerList, length)
+}
+
+func (e *msgpackEncDriver) WriteMapStart(length int) {
+	e.writeContainerLen(msgpackContainerMap, length)
+}
+
+func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
+	slen := len(s)
+	if c == cRAW && e.h.WriteExt {
+		e.writeContainerLen(msgpackContainerBin, slen)
+	} else {
+		e.writeContainerLen(msgpackContainerStr, slen)
+	}
+	if slen > 0 {
+		e.w.writestr(s)
+	}
+}
+
+func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
+	if bs == nil {
+		e.EncodeNil()
+		return
+	}
+	slen := len(bs)
+	if c == cRAW && e.h.WriteExt {
+		e.writeContainerLen(msgpackContainerBin, slen)
+	} else {
+		e.writeContainerLen(msgpackContainerStr, slen)
+	}
+	if slen > 0 {
+		e.w.writeb(bs)
+	}
+}
+
+func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
+	if ct.hasFixMin && l < ct.fixCutoff {
+		e.w.writen1(ct.bFixMin | byte(l))
+	} else if ct.has8 && l < 256 && (ct.has8Always || e.h.WriteExt) {
+		e.w.writen2(ct.b8, uint8(l))
+	} else if l < 65536 {
+		e.w.writen1(ct.b16)
+		bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l))
+	} else {
+		e.w.writen1(ct.b32)
+		bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l))
+	}
+}
+
+//---------------------------------------------
+
+type msgpackDecDriver struct {
+	d *Decoder
+	r decReader // *Decoder decReader decReaderT
+	h *MsgpackHandle
+	// b      [scratchByteArrayLen]byte
+	bd     byte
+	bdRead bool
+	br     bool // bytes reader
+	noBuiltInTypes
+	// noStreamingCodec
+	// decNoSeparator
+	decDriverNoopContainerReader
+	_ [3]uint64 // padding
+}
+
+// Note: This returns either a primitive (int, bool, etc) for non-containers,
+// or a containerType, or a specific type denoting nil or extension.
+// It is called when a nil interface{} is passed, leaving it up to the DecDriver
+// to introspect the stream and decide how best to decode.
+// It deciphers the value by looking at the stream first.
+func (d *msgpackDecDriver) DecodeNaked() {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	bd := d.bd
+	n := d.d.n
+	var decodeFurther bool
+
+	switch bd {
+	case mpNil:
+		n.v = valueTypeNil
+		d.bdRead = false
+	case mpFalse:
+		n.v = valueTypeBool
+		n.b = false
+	case mpTrue:
+		n.v = valueTypeBool
+		n.b = true
+
+	case mpFloat:
+		n.v = valueTypeFloat
+		n.f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
+	case mpDouble:
+		n.v = valueTypeFloat
+		n.f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
+
+	case mpUint8:
+		n.v = valueTypeUint
+		n.u = uint64(d.r.readn1())
+	case mpUint16:
+		n.v = valueTypeUint
+		n.u = uint64(bigen.Uint16(d.r.readx(2)))
+	case mpUint32:
+		n.v = valueTypeUint
+		n.u = uint64(bigen.Uint32(d.r.readx(4)))
+	case mpUint64:
+		n.v = valueTypeUint
+		n.u = uint64(bigen.Uint64(d.r.readx(8)))
+
+	case mpInt8:
+		n.v = valueTypeInt
+		n.i = int64(int8(d.r.readn1()))
+	case mpInt16:
+		n.v = valueTypeInt
+		n.i = int64(int16(bigen.Uint16(d.r.readx(2))))
+	case mpInt32:
+		n.v = valueTypeInt
+		n.i = int64(int32(bigen.Uint32(d.r.readx(4))))
+	case mpInt64:
+		n.v = valueTypeInt
+		n.i = int64(int64(bigen.Uint64(d.r.readx(8))))
+
+	default:
+		switch {
+		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
+			// positive fixnum (always signed)
+			n.v = valueTypeInt
+			n.i = int64(int8(bd))
+		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
+			// negative fixnum
+			n.v = valueTypeInt
+			n.i = int64(int8(bd))
+		case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax:
+			if d.h.RawToString {
+				n.v = valueTypeString
+				n.s = d.DecodeString()
+			} else {
+				n.v = valueTypeBytes
+				n.l = d.DecodeBytes(nil, false)
+			}
+		case bd == mpBin8, bd == mpBin16, bd == mpBin32:
+			n.v = valueTypeBytes
+			n.l = d.DecodeBytes(nil, false)
+		case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax:
+			n.v = valueTypeArray
+			decodeFurther = true
+		case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax:
+			n.v = valueTypeMap
+			decodeFurther = true
+		case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32:
+			n.v = valueTypeExt
+			clen := d.readExtLen()
+			n.u = uint64(d.r.readn1())
+			if n.u == uint64(mpTimeExtTagU) {
+				n.v = valueTypeTime
+				n.t = d.decodeTime(clen)
+			} else {
+				n.l = d.r.readx(clen)
+			}
+		default:
+			d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd))
+		}
+	}
+	if !decodeFurther {
+		d.bdRead = false
+	}
+	if n.v == valueTypeUint && d.h.SignedInteger {
+		n.v = valueTypeInt
+		n.i = int64(n.u)
+	}
+	return
+}
+
+// int can be decoded from msgpack type: intXXX or uintXXX
+func (d *msgpackDecDriver) DecodeInt64() (i int64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch d.bd {
+	case mpUint8:
+		i = int64(uint64(d.r.readn1()))
+	case mpUint16:
+		i = int64(uint64(bigen.Uint16(d.r.readx(2))))
+	case mpUint32:
+		i = int64(uint64(bigen.Uint32(d.r.readx(4))))
+	case mpUint64:
+		i = int64(bigen.Uint64(d.r.readx(8)))
+	case mpInt8:
+		i = int64(int8(d.r.readn1()))
+	case mpInt16:
+		i = int64(int16(bigen.Uint16(d.r.readx(2))))
+	case mpInt32:
+		i = int64(int32(bigen.Uint32(d.r.readx(4))))
+	case mpInt64:
+		i = int64(bigen.Uint64(d.r.readx(8)))
+	default:
+		switch {
+		case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax:
+			i = int64(int8(d.bd))
+		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
+			i = int64(int8(d.bd))
+		default:
+			d.d.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+			return
+		}
+	}
+	d.bdRead = false
+	return
+}
+
+// uint can be decoded from msgpack type: intXXX or uintXXX
+func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch d.bd {
+	case mpUint8:
+		ui = uint64(d.r.readn1())
+	case mpUint16:
+		ui = uint64(bigen.Uint16(d.r.readx(2)))
+	case mpUint32:
+		ui = uint64(bigen.Uint32(d.r.readx(4)))
+	case mpUint64:
+		ui = bigen.Uint64(d.r.readx(8))
+	case mpInt8:
+		if i := int64(int8(d.r.readn1())); i >= 0 {
+			ui = uint64(i)
+		} else {
+			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			return
+		}
+	case mpInt16:
+		if i := int64(int16(bigen.Uint16(d.r.readx(2)))); i >= 0 {
+			ui = uint64(i)
+		} else {
+			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			return
+		}
+	case mpInt32:
+		if i := int64(int32(bigen.Uint32(d.r.readx(4)))); i >= 0 {
+			ui = uint64(i)
+		} else {
+			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			return
+		}
+	case mpInt64:
+		if i := int64(bigen.Uint64(d.r.readx(8))); i >= 0 {
+			ui = uint64(i)
+		} else {
+			d.d.errorf("assigning negative signed value: %v, to unsigned type", i)
+			return
+		}
+	default:
+		switch {
+		case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax:
+			ui = uint64(d.bd)
+		case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax:
+			d.d.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd))
+			return
+		default:
+			d.d.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+			return
+		}
+	}
+	d.bdRead = false
+	return
+}
+
+// float can either be decoded from msgpack type: float, double or intX
+func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == mpFloat {
+		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
+	} else if d.bd == mpDouble {
+		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
+	} else {
+		f = float64(d.DecodeInt64())
+	}
+	d.bdRead = false
+	return
+}
+
+// bool can be decoded from bool, fixnum 0 or 1.
+func (d *msgpackDecDriver) DecodeBool() (b bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == mpFalse || d.bd == 0 {
+		// b = false
+	} else if d.bd == mpTrue || d.bd == 1 {
+		b = true
+	} else {
+		d.d.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd))
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+
+	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
+	bd := d.bd
+	// DecodeBytes could be from: bin str fixstr fixarray array ...
+	var clen int
+	vt := d.ContainerType()
+	switch vt {
+	case valueTypeBytes:
+		// valueTypeBytes may be a mpBin or an mpStr container
+		if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
+			clen = d.readContainerLen(msgpackContainerBin)
+		} else {
+			clen = d.readContainerLen(msgpackContainerStr)
+		}
+	case valueTypeString:
+		clen = d.readContainerLen(msgpackContainerStr)
+	case valueTypeArray:
+		if zerocopy && len(bs) == 0 {
+			bs = d.d.b[:]
+		}
+		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
+		return
+	default:
+		d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt))
+		return
+	}
+
+	// these are (bin|str)(8|16|32)
+	d.bdRead = false
+	// bytes may be nil, so handle it. if nil, clen=-1.
+	if clen < 0 {
+		return nil
+	}
+	if zerocopy {
+		if d.br {
+			return d.r.readx(clen)
+		} else if len(bs) == 0 {
+			bs = d.d.b[:]
+		}
+	}
+	return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
+}
+
+func (d *msgpackDecDriver) DecodeString() (s string) {
+	return string(d.DecodeBytes(d.d.b[:], true))
+}
+
+func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
+	return d.DecodeBytes(d.d.b[:], true)
+}
+
+func (d *msgpackDecDriver) readNextBd() {
+	d.bd = d.r.readn1()
+	d.bdRead = true
+}
+
+func (d *msgpackDecDriver) uncacheRead() {
+	if d.bdRead {
+		d.r.unreadn1()
+		d.bdRead = false
+	}
+}
+
+func (d *msgpackDecDriver) ContainerType() (vt valueType) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	bd := d.bd
+	if bd == mpNil {
+		return valueTypeNil
+	} else if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 ||
+		(!d.h.RawToString &&
+			(bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax))) {
+		return valueTypeBytes
+	} else if d.h.RawToString &&
+		(bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax)) {
+		return valueTypeString
+	} else if bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) {
+		return valueTypeArray
+	} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
+		return valueTypeMap
+	}
+	// else {
+	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
+	// }
+	return valueTypeUnset
+}
+
+func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == mpNil {
+		d.bdRead = false
+		return true
+	}
+	return
+}
+
+func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) {
+	bd := d.bd
+	if bd == mpNil {
+		clen = -1 // to represent nil
+	} else if bd == ct.b8 {
+		clen = int(d.r.readn1())
+	} else if bd == ct.b16 {
+		clen = int(bigen.Uint16(d.r.readx(2)))
+	} else if bd == ct.b32 {
+		clen = int(bigen.Uint32(d.r.readx(4)))
+	} else if (ct.bFixMin & bd) == ct.bFixMin {
+		clen = int(ct.bFixMin ^ bd)
+	} else {
+		d.d.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd)
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *msgpackDecDriver) ReadMapStart() int {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	return d.readContainerLen(msgpackContainerMap)
+}
+
+func (d *msgpackDecDriver) ReadArrayStart() int {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	return d.readContainerLen(msgpackContainerList)
+}
+
+func (d *msgpackDecDriver) readExtLen() (clen int) {
+	switch d.bd {
+	case mpNil:
+		clen = -1 // to represent nil
+	case mpFixExt1:
+		clen = 1
+	case mpFixExt2:
+		clen = 2
+	case mpFixExt4:
+		clen = 4
+	case mpFixExt8:
+		clen = 8
+	case mpFixExt16:
+		clen = 16
+	case mpExt8:
+		clen = int(d.r.readn1())
+	case mpExt16:
+		clen = int(bigen.Uint16(d.r.readx(2)))
+	case mpExt32:
+		clen = int(bigen.Uint32(d.r.readx(4)))
+	default:
+		d.d.errorf("decoding ext bytes: found unexpected byte: %x", d.bd)
+		return
+	}
+	return
+}
+
+func (d *msgpackDecDriver) DecodeTime() (t time.Time) {
+	// decode time from string bytes or ext
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == mpNil {
+		d.bdRead = false
+		return
+	}
+	var clen int
+	switch d.ContainerType() {
+	case valueTypeBytes, valueTypeString:
+		clen = d.readContainerLen(msgpackContainerStr)
+	default:
+		// expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1
+		d.bdRead = false
+		b2 := d.r.readn1()
+		if d.bd == mpFixExt4 && b2 == mpTimeExtTagU {
+			clen = 4
+		} else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU {
+			clen = 8
+		} else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU {
+			clen = 12
+		} else {
+			d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2)
+			return
+		}
+	}
+	return d.decodeTime(clen)
+}
+
+func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) {
+	// bs = d.r.readx(clen)
+	d.bdRead = false
+	switch clen {
+	case 4:
+		t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC()
+	case 8:
+		tv := bigen.Uint64(d.r.readx(8))
+		t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC()
+	case 12:
+		nsec := bigen.Uint32(d.r.readx(4))
+		sec := bigen.Uint64(d.r.readx(8))
+		t = time.Unix(int64(sec), int64(nsec)).UTC()
+	default:
+		d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen)
+		return
+	}
+	return
+}
+
+func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
+	if xtag > 0xff {
+		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		return
+	}
+	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
+	realxtag = uint64(realxtag1)
+	if ext == nil {
+		re := rv.(*RawExt)
+		re.Tag = realxtag
+		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
+	} else {
+		ext.ReadExt(rv, xbs)
+	}
+	return
+}
+
+func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	xbd := d.bd
+	if xbd == mpBin8 || xbd == mpBin16 || xbd == mpBin32 {
+		xbs = d.DecodeBytes(nil, true)
+	} else if xbd == mpStr8 || xbd == mpStr16 || xbd == mpStr32 ||
+		(xbd >= mpFixStrMin && xbd <= mpFixStrMax) {
+		xbs = d.DecodeStringAsBytes()
+	} else {
+		clen := d.readExtLen()
+		xtag = d.r.readn1()
+		if verifyTag && xtag != tag {
+			d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag)
+			return
+		}
+		xbs = d.r.readx(clen)
+	}
+	d.bdRead = false
+	return
+}
+
+//--------------------------------------------------
+
+//MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format.
+type MsgpackHandle struct {
+	BasicHandle
+
+	// RawToString controls how raw bytes are decoded into a nil interface{}.
+	RawToString bool
+
+	// NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum.
+	NoFixedNum bool
+
+	// WriteExt flag supports encoding configured extensions with extension tags.
+	// It also controls whether other elements of the new spec are encoded (ie Str8).
+	//
+	// With WriteExt=false, configured extensions are serialized as raw bytes
+	// and Str8 is not encoded.
+	//
+	// A stream can still be decoded into a typed value, provided an appropriate value
+	// is provided, but the type cannot be inferred from the stream. If no appropriate
+	// type is provided (e.g. decoding into a nil interface{}), you get back
+	// a []byte or string based on the setting of RawToString.
+	WriteExt bool
+
+	binaryEncodingType
+	noElemSeparators
+
+	// _ [1]uint64 // padding
+}
+
+// Name returns the name of the handle: msgpack
+func (h *MsgpackHandle) Name() string { return "msgpack" }
+
+// SetBytesExt sets an extension
+func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+}
+
+func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
+	return &msgpackEncDriver{e: e, w: e.w, h: h}
+}
+
+func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver {
+	return &msgpackDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+}
+
+func (e *msgpackEncDriver) reset() {
+	e.w = e.e.w
+}
+
+func (d *msgpackDecDriver) reset() {
+	d.r, d.br = d.d.r, d.d.bytes
+	d.bd, d.bdRead = 0, false
+}
+
+//--------------------------------------------------
+
+type msgpackSpecRpcCodec struct {
+	rpcCodec
+}
+
+// /////////////// Spec RPC Codec ///////////////////
+func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
+	// WriteRequest can write to both a Go service, and other services that do
+	// not abide by the 1 argument rule of a Go service.
+	// We discriminate based on if the body is a MsgpackSpecRpcMultiArgs
+	var bodyArr []interface{}
+	if m, ok := body.(MsgpackSpecRpcMultiArgs); ok {
+		bodyArr = ([]interface{})(m)
+	} else {
+		bodyArr = []interface{}{body}
+	}
+	r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
+	return c.write(r2, nil, false)
+}
+
+func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
+	var moe interface{}
+	if r.Error != "" {
+		moe = r.Error
+	}
+	if moe != nil && body != nil {
+		body = nil
+	}
+	r2 := []interface{}{1, uint32(r.Seq), moe, body}
+	return c.write(r2, nil, false)
+}
+
+func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
+	return c.parseCustomHeader(1, &r.Seq, &r.Error)
+}
+
+func (c *msgpackSpecRpcCodec) ReadRequestHeader(r *rpc.Request) error {
+	return c.parseCustomHeader(0, &r.Seq, &r.ServiceMethod)
+}
+
+func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error {
+	if body == nil { // read and discard
+		return c.read(nil)
+	}
+	bodyArr := []interface{}{body}
+	return c.read(&bodyArr)
+}
+
+func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
+	if c.isClosed() {
+		return io.EOF
+	}
+
+	// We read the response header by hand
+	// so that the body can be decoded on its own from the stream at a later time.
+
+	const fia byte = 0x94 //four item array descriptor value
+	// Not sure why the panic of EOF is swallowed above.
+	// if bs1 := c.dec.r.readn1(); bs1 != fia {
+	// 	err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1)
+	// 	return
+	// }
+	var ba [1]byte
+	var n int
+	for {
+		n, err = c.r.Read(ba[:])
+		if err != nil {
+			return
+		}
+		if n == 1 {
+			break
+		}
+	}
+
+	var b = ba[0]
+	if b != fia {
+		err = fmt.Errorf("not array - %s %x/%s", msgBadDesc, b, mpdesc(b))
+	} else {
+		err = c.read(&b)
+		if err == nil {
+			if b != expectTypeByte {
+				err = fmt.Errorf("%s - expecting %v but got %x/%s",
+					msgBadDesc, expectTypeByte, b, mpdesc(b))
+			} else {
+				err = c.read(msgid)
+				if err == nil {
+					err = c.read(methodOrError)
+				}
+			}
+		}
+	}
+	return
+}
+
+//--------------------------------------------------
+
+// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol
+// as defined in the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
+type msgpackSpecRpc struct{}
+
+// MsgpackSpecRpc implements Rpc using the communication protocol defined in
+// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
+//
+// See GoRpc documentation, for information on buffering for better performance.
+var MsgpackSpecRpc msgpackSpecRpc
+
+func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
+	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
+}
+
+func (x msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
+	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
+}
+
+var _ decDriver = (*msgpackDecDriver)(nil)
+var _ encDriver = (*msgpackEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/rpc.go b/vendor/github.com/ugorji/go/codec/rpc.go
new file mode 100644
index 0000000..9fb3c01
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/rpc.go
@@ -0,0 +1,232 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"bufio"
+	"errors"
+	"io"
+	"net/rpc"
+	"sync"
+)
+
+// Rpc provides a rpc Server or Client Codec for rpc communication.
+type Rpc interface {
+	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
+	ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
+}
+
+// RPCOptions holds options specific to rpc functionality
+type RPCOptions struct {
+	// RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
+	//
+	// Set RPCNoBuffer=true to turn buffering off.
+	// Buffering can still be done if buffered connections are passed in, or
+	// buffering is configured on the handle.
+	RPCNoBuffer bool
+}
+
+// rpcCodec defines the struct members and common methods.
+type rpcCodec struct {
+	c io.Closer
+	r io.Reader
+	w io.Writer
+	f ioFlusher
+
+	dec *Decoder
+	enc *Encoder
+	// bw  *bufio.Writer
+	// br  *bufio.Reader
+	mu sync.Mutex
+	h  Handle
+
+	cls    bool
+	clsmu  sync.RWMutex
+	clsErr error
+}
+
+func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
+	// return newRPCCodec2(bufio.NewReader(conn), bufio.NewWriter(conn), conn, h)
+	return newRPCCodec2(conn, conn, conn, h)
+}
+
+func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
+	// defensive: ensure that jsonH has TermWhitespace turned on.
+	if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
+		panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
+	}
+	// always ensure that we use a flusher, and always flush what was written to the connection.
+	// we lose nothing by using a buffered writer internally.
+	f, ok := w.(ioFlusher)
+	bh := h.getBasicHandle()
+	if !bh.RPCNoBuffer {
+		if bh.WriterBufferSize <= 0 {
+			if !ok {
+				bw := bufio.NewWriter(w)
+				f, w = bw, bw
+			}
+		}
+		if bh.ReaderBufferSize <= 0 {
+			if _, ok = w.(ioPeeker); !ok {
+				if _, ok = w.(ioBuffered); !ok {
+					br := bufio.NewReader(r)
+					r = br
+				}
+			}
+		}
+	}
+	return rpcCodec{
+		c:   c,
+		w:   w,
+		r:   r,
+		f:   f,
+		h:   h,
+		enc: NewEncoder(w, h),
+		dec: NewDecoder(r, h),
+	}
+}
+
+func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
+	if c.isClosed() {
+		return c.clsErr
+	}
+	err = c.enc.Encode(obj1)
+	if err == nil {
+		if writeObj2 {
+			err = c.enc.Encode(obj2)
+		}
+		// if err == nil && c.f != nil {
+		// 	err = c.f.Flush()
+		// }
+	}
+	if c.f != nil {
+		if err == nil {
+			err = c.f.Flush()
+		} else {
+			_ = c.f.Flush() // swallow flush error, so we maintain prior error on write
+		}
+	}
+	return
+}
+
+func (c *rpcCodec) swallow(err *error) {
+	defer panicToErr(c.dec, err)
+	c.dec.swallow()
+}
+
+func (c *rpcCodec) read(obj interface{}) (err error) {
+	if c.isClosed() {
+		return c.clsErr
+	}
+	//If nil is passed in, we should read and discard
+	if obj == nil {
+		// var obj2 interface{}
+		// return c.dec.Decode(&obj2)
+		c.swallow(&err)
+		return
+	}
+	return c.dec.Decode(obj)
+}
+
+func (c *rpcCodec) isClosed() (b bool) {
+	if c.c != nil {
+		c.clsmu.RLock()
+		b = c.cls
+		c.clsmu.RUnlock()
+	}
+	return
+}
+
+func (c *rpcCodec) Close() error {
+	if c.c == nil || c.isClosed() {
+		return c.clsErr
+	}
+	c.clsmu.Lock()
+	c.cls = true
+	c.clsErr = c.c.Close()
+	c.clsmu.Unlock()
+	return c.clsErr
+}
+
+func (c *rpcCodec) ReadResponseBody(body interface{}) error {
+	return c.read(body)
+}
+
+// -------------------------------------
+
+type goRpcCodec struct {
+	rpcCodec
+}
+
+func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
+	// Must protect for concurrent access as per API
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.write(r, body, true)
+}
+
+func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.write(r, body, true)
+}
+
+func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
+	return c.read(r)
+}
+
+func (c *goRpcCodec) ReadRequestHeader(r *rpc.Request) error {
+	return c.read(r)
+}
+
+func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
+	return c.read(body)
+}
+
+// -------------------------------------
+
+// goRpc is the implementation of Rpc that uses the communication protocol
+// as defined in net/rpc package.
+type goRpc struct{}
+
+// GoRpc implements Rpc using the communication protocol defined in net/rpc package.
+//
+// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
+//
+// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
+// This ensures we use an adequate buffer during reading and writing.
+// If not configured, we will internally initialize and use a buffer during reads and writes.
+// This can be turned off via the RPCNoBuffer option on the Handle.
+//   var handle codec.JsonHandle
+//   handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
+//
+// Example 1: one way of configuring buffering explicitly:
+//   var handle codec.JsonHandle // codec handle
+//   handle.ReaderBufferSize = 1024
+//   handle.WriterBufferSize = 1024
+//   var conn io.ReadWriteCloser // connection got from a socket
+//   var serverCodec = GoRpc.ServerCodec(conn, handle)
+//   var clientCodec = GoRpc.ClientCodec(conn, handle)
+//
+// Example 2: you can also explicitly create a buffered connection yourself,
+// and not worry about configuring the buffer sizes in the Handle.
+//   var handle codec.Handle     // codec handle
+//   var conn io.ReadWriteCloser // connection got from a socket
+//   var bufconn = struct {      // bufconn here is a buffered io.ReadWriteCloser
+//       io.Closer
+//       *bufio.Reader
+//       *bufio.Writer
+//   }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
+//   var serverCodec = GoRpc.ServerCodec(bufconn, handle)
+//   var clientCodec = GoRpc.ClientCodec(bufconn, handle)
+//
+var GoRpc goRpc
+
+func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
+	return &goRpcCodec{newRPCCodec(conn, h)}
+}
+
+func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
+	return &goRpcCodec{newRPCCodec(conn, h)}
+}
diff --git a/vendor/github.com/ugorji/go/codec/simple.go b/vendor/github.com/ugorji/go/codec/simple.go
new file mode 100644
index 0000000..f1e181e
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/simple.go
@@ -0,0 +1,652 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+package codec
+
+import (
+	"math"
+	"reflect"
+	"time"
+)
+
+const (
+	_               uint8 = iota
+	simpleVdNil           = 1
+	simpleVdFalse         = 2
+	simpleVdTrue          = 3
+	simpleVdFloat32       = 4
+	simpleVdFloat64       = 5
+
+	// each lasts for 4 (ie n, n+1, n+2, n+3)
+	simpleVdPosInt = 8
+	simpleVdNegInt = 12
+
+	simpleVdTime = 24
+
+	// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
+	simpleVdString    = 216
+	simpleVdByteArray = 224
+	simpleVdArray     = 232
+	simpleVdMap       = 240
+	simpleVdExt       = 248
+)
+
+type simpleEncDriver struct {
+	noBuiltInTypes
+	// encNoSeparator
+	e *Encoder
+	h *SimpleHandle
+	w encWriter
+	b [8]byte
+	// c containerState
+	encDriverTrackContainerWriter
+	// encDriverNoopContainerWriter
+	_ [2]uint64 // padding
+}
+
+func (e *simpleEncDriver) EncodeNil() {
+	e.w.writen1(simpleVdNil)
+}
+
+func (e *simpleEncDriver) EncodeBool(b bool) {
+	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
+		e.EncodeNil()
+		return
+	}
+	if b {
+		e.w.writen1(simpleVdTrue)
+	} else {
+		e.w.writen1(simpleVdFalse)
+	}
+}
+
+func (e *simpleEncDriver) EncodeFloat32(f float32) {
+	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
+		e.EncodeNil()
+		return
+	}
+	e.w.writen1(simpleVdFloat32)
+	bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
+}
+
+func (e *simpleEncDriver) EncodeFloat64(f float64) {
+	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
+		e.EncodeNil()
+		return
+	}
+	e.w.writen1(simpleVdFloat64)
+	bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
+}
+
+func (e *simpleEncDriver) EncodeInt(v int64) {
+	if v < 0 {
+		e.encUint(uint64(-v), simpleVdNegInt)
+	} else {
+		e.encUint(uint64(v), simpleVdPosInt)
+	}
+}
+
+func (e *simpleEncDriver) EncodeUint(v uint64) {
+	e.encUint(v, simpleVdPosInt)
+}
+
+func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
+	if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
+		e.EncodeNil()
+		return
+	}
+	if v <= math.MaxUint8 {
+		e.w.writen2(bd, uint8(v))
+	} else if v <= math.MaxUint16 {
+		e.w.writen1(bd + 1)
+		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
+	} else if v <= math.MaxUint32 {
+		e.w.writen1(bd + 2)
+		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
+	} else { // if v <= math.MaxUint64 {
+		e.w.writen1(bd + 3)
+		bigenHelper{e.b[:8], e.w}.writeUint64(v)
+	}
+}
+
+func (e *simpleEncDriver) encLen(bd byte, length int) {
+	if length == 0 {
+		e.w.writen1(bd)
+	} else if length <= math.MaxUint8 {
+		e.w.writen1(bd + 1)
+		e.w.writen1(uint8(length))
+	} else if length <= math.MaxUint16 {
+		e.w.writen1(bd + 2)
+		bigenHelper{e.b[:2], e.w}.writeUint16(uint16(length))
+	} else if int64(length) <= math.MaxUint32 {
+		e.w.writen1(bd + 3)
+		bigenHelper{e.b[:4], e.w}.writeUint32(uint32(length))
+	} else {
+		e.w.writen1(bd + 4)
+		bigenHelper{e.b[:8], e.w}.writeUint64(uint64(length))
+	}
+}
+
+func (e *simpleEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
+	bs := ext.WriteExt(rv)
+	if bs == nil {
+		e.EncodeNil()
+		return
+	}
+	e.encodeExtPreamble(uint8(xtag), len(bs))
+	e.w.writeb(bs)
+}
+
+func (e *simpleEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
+	e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
+	e.w.writeb(re.Data)
+}
+
+func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
+	e.encLen(simpleVdExt, length)
+	e.w.writen1(xtag)
+}
+
+func (e *simpleEncDriver) WriteArrayStart(length int) {
+	e.c = containerArrayStart
+	e.encLen(simpleVdArray, length)
+}
+
+func (e *simpleEncDriver) WriteMapStart(length int) {
+	e.c = containerMapStart
+	e.encLen(simpleVdMap, length)
+}
+
+func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
+	if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
+		e.EncodeNil()
+		return
+	}
+	e.encLen(simpleVdString, len(v))
+	e.w.writestr(v)
+}
+
+// func (e *simpleEncDriver) EncodeSymbol(v string) {
+// 	e.EncodeString(cUTF8, v)
+// }
+
+func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
+	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
+	if v == nil {
+		e.EncodeNil()
+		return
+	}
+	e.encLen(simpleVdByteArray, len(v))
+	e.w.writeb(v)
+}
+
+func (e *simpleEncDriver) EncodeTime(t time.Time) {
+	// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
+	if t.IsZero() {
+		e.EncodeNil()
+		return
+	}
+	v, err := t.MarshalBinary()
+	if err != nil {
+		e.e.errorv(err)
+		return
+	}
+	// time.Time marshalbinary takes about 14 bytes.
+	e.w.writen2(simpleVdTime, uint8(len(v)))
+	e.w.writeb(v)
+}
+
+//------------------------------------
+
+type simpleDecDriver struct {
+	d      *Decoder
+	h      *SimpleHandle
+	r      decReader
+	bdRead bool
+	bd     byte
+	br     bool // a bytes reader?
+	c      containerState
+	// b      [scratchByteArrayLen]byte
+	noBuiltInTypes
+	// noStreamingCodec
+	decDriverNoopContainerReader
+	_ [3]uint64 // padding
+}
+
+func (d *simpleDecDriver) readNextBd() {
+	d.bd = d.r.readn1()
+	d.bdRead = true
+}
+
+func (d *simpleDecDriver) uncacheRead() {
+	if d.bdRead {
+		d.r.unreadn1()
+		d.bdRead = false
+	}
+}
+
+func (d *simpleDecDriver) ContainerType() (vt valueType) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch d.bd {
+	case simpleVdNil:
+		return valueTypeNil
+	case simpleVdByteArray, simpleVdByteArray + 1,
+		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+		return valueTypeBytes
+	case simpleVdString, simpleVdString + 1,
+		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
+		return valueTypeString
+	case simpleVdArray, simpleVdArray + 1,
+		simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
+		return valueTypeArray
+	case simpleVdMap, simpleVdMap + 1,
+		simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
+		return valueTypeMap
+		// case simpleVdTime:
+		// 	return valueTypeTime
+	}
+	// else {
+	// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
+	// }
+	return valueTypeUnset
+}
+
+func (d *simpleDecDriver) TryDecodeAsNil() bool {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == simpleVdNil {
+		d.bdRead = false
+		return true
+	}
+	return false
+}
+
+func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch d.bd {
+	case simpleVdPosInt:
+		ui = uint64(d.r.readn1())
+	case simpleVdPosInt + 1:
+		ui = uint64(bigen.Uint16(d.r.readx(2)))
+	case simpleVdPosInt + 2:
+		ui = uint64(bigen.Uint32(d.r.readx(4)))
+	case simpleVdPosInt + 3:
+		ui = uint64(bigen.Uint64(d.r.readx(8)))
+	case simpleVdNegInt:
+		ui = uint64(d.r.readn1())
+		neg = true
+	case simpleVdNegInt + 1:
+		ui = uint64(bigen.Uint16(d.r.readx(2)))
+		neg = true
+	case simpleVdNegInt + 2:
+		ui = uint64(bigen.Uint32(d.r.readx(4)))
+		neg = true
+	case simpleVdNegInt + 3:
+		ui = uint64(bigen.Uint64(d.r.readx(8)))
+		neg = true
+	default:
+		d.d.errorf("integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
+		return
+	}
+	// don't do this check, because callers may only want the unsigned value.
+	// if ui > math.MaxInt64 {
+	// 	d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui)
+	//		return
+	// }
+	return
+}
+
+func (d *simpleDecDriver) DecodeInt64() (i int64) {
+	ui, neg := d.decCheckInteger()
+	i = chkOvf.SignedIntV(ui)
+	if neg {
+		i = -i
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
+	ui, neg := d.decCheckInteger()
+	if neg {
+		d.d.errorf("assigning negative signed value to unsigned type")
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *simpleDecDriver) DecodeFloat64() (f float64) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == simpleVdFloat32 {
+		f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
+	} else if d.bd == simpleVdFloat64 {
+		f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
+	} else {
+		if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
+			f = float64(d.DecodeInt64())
+		} else {
+			d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd)
+			return
+		}
+	}
+	d.bdRead = false
+	return
+}
+
+// bool can be decoded from bool only (single byte).
+func (d *simpleDecDriver) DecodeBool() (b bool) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == simpleVdTrue {
+		b = true
+	} else if d.bd == simpleVdFalse {
+	} else {
+		d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd)
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *simpleDecDriver) ReadMapStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	d.bdRead = false
+	d.c = containerMapStart
+	return d.decLen()
+}
+
+func (d *simpleDecDriver) ReadArrayStart() (length int) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	d.bdRead = false
+	d.c = containerArrayStart
+	return d.decLen()
+}
+
+func (d *simpleDecDriver) ReadArrayElem() {
+	d.c = containerArrayElem
+}
+
+func (d *simpleDecDriver) ReadArrayEnd() {
+	d.c = containerArrayEnd
+}
+
+func (d *simpleDecDriver) ReadMapElemKey() {
+	d.c = containerMapKey
+}
+
+func (d *simpleDecDriver) ReadMapElemValue() {
+	d.c = containerMapValue
+}
+
+func (d *simpleDecDriver) ReadMapEnd() {
+	d.c = containerMapEnd
+}
+
+func (d *simpleDecDriver) decLen() int {
+	switch d.bd % 8 {
+	case 0:
+		return 0
+	case 1:
+		return int(d.r.readn1())
+	case 2:
+		return int(bigen.Uint16(d.r.readx(2)))
+	case 3:
+		ui := uint64(bigen.Uint32(d.r.readx(4)))
+		if chkOvf.Uint(ui, intBitsize) {
+			d.d.errorf("overflow integer: %v", ui)
+			return 0
+		}
+		return int(ui)
+	case 4:
+		ui := bigen.Uint64(d.r.readx(8))
+		if chkOvf.Uint(ui, intBitsize) {
+			d.d.errorf("overflow integer: %v", ui)
+			return 0
+		}
+		return int(ui)
+	}
+	d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
+	return -1
+}
+
+func (d *simpleDecDriver) DecodeString() (s string) {
+	return string(d.DecodeBytes(d.d.b[:], true))
+}
+
+func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
+	return d.DecodeBytes(d.d.b[:], true)
+}
+
+func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == simpleVdNil {
+		d.bdRead = false
+		return
+	}
+	// check if an "array" of uint8's (see ContainerType for how to infer if an array)
+	if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
+		if len(bs) == 0 && zerocopy {
+			bs = d.d.b[:]
+		}
+		bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
+		return
+	}
+
+	clen := d.decLen()
+	d.bdRead = false
+	if zerocopy {
+		if d.br {
+			return d.r.readx(clen)
+		} else if len(bs) == 0 {
+			bs = d.d.b[:]
+		}
+	}
+	return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
+}
+
+func (d *simpleDecDriver) DecodeTime() (t time.Time) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	if d.bd == simpleVdNil {
+		d.bdRead = false
+		return
+	}
+	if d.bd != simpleVdTime {
+		d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
+		return
+	}
+	d.bdRead = false
+	clen := int(d.r.readn1())
+	b := d.r.readx(clen)
+	if err := (&t).UnmarshalBinary(b); err != nil {
+		d.d.errorv(err)
+	}
+	return
+}
+
+func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
+	if xtag > 0xff {
+		d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
+		return
+	}
+	realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
+	realxtag = uint64(realxtag1)
+	if ext == nil {
+		re := rv.(*RawExt)
+		re.Tag = realxtag
+		re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
+	} else {
+		ext.ReadExt(rv, xbs)
+	}
+	return
+}
+
+func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+	switch d.bd {
+	case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
+		l := d.decLen()
+		xtag = d.r.readn1()
+		if verifyTag && xtag != tag {
+			d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
+			return
+		}
+		xbs = d.r.readx(l)
+	case simpleVdByteArray, simpleVdByteArray + 1,
+		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+		xbs = d.DecodeBytes(nil, true)
+	default:
+		d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd)
+		return
+	}
+	d.bdRead = false
+	return
+}
+
+func (d *simpleDecDriver) DecodeNaked() {
+	if !d.bdRead {
+		d.readNextBd()
+	}
+
+	n := d.d.n
+	var decodeFurther bool
+
+	switch d.bd {
+	case simpleVdNil:
+		n.v = valueTypeNil
+	case simpleVdFalse:
+		n.v = valueTypeBool
+		n.b = false
+	case simpleVdTrue:
+		n.v = valueTypeBool
+		n.b = true
+	case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
+		if d.h.SignedInteger {
+			n.v = valueTypeInt
+			n.i = d.DecodeInt64()
+		} else {
+			n.v = valueTypeUint
+			n.u = d.DecodeUint64()
+		}
+	case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
+		n.v = valueTypeInt
+		n.i = d.DecodeInt64()
+	case simpleVdFloat32:
+		n.v = valueTypeFloat
+		n.f = d.DecodeFloat64()
+	case simpleVdFloat64:
+		n.v = valueTypeFloat
+		n.f = d.DecodeFloat64()
+	case simpleVdTime:
+		n.v = valueTypeTime
+		n.t = d.DecodeTime()
+	case simpleVdString, simpleVdString + 1,
+		simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
+		n.v = valueTypeString
+		n.s = d.DecodeString()
+	case simpleVdByteArray, simpleVdByteArray + 1,
+		simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
+		n.v = valueTypeBytes
+		n.l = d.DecodeBytes(nil, false)
+	case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
+		n.v = valueTypeExt
+		l := d.decLen()
+		n.u = uint64(d.r.readn1())
+		n.l = d.r.readx(l)
+	case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
+		simpleVdArray + 3, simpleVdArray + 4:
+		n.v = valueTypeArray
+		decodeFurther = true
+	case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
+		n.v = valueTypeMap
+		decodeFurther = true
+	default:
+		d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd)
+	}
+
+	if !decodeFurther {
+		d.bdRead = false
+	}
+	return
+}
+
+//------------------------------------
+
+// SimpleHandle is a Handle for a very simple encoding format.
+//
+// simple is a simplistic codec similar to binc, but not as compact.
+//   - Encoding of a value is always preceded by the descriptor byte (bd)
+//   - True, false, nil are encoded fully in 1 byte (the descriptor)
+//   - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
+//     There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
+//   - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
+//   - Length of containers (strings, bytes, array, map, extensions)
+//     are encoded in 0, 1, 2, 4 or 8 bytes.
+//     Zero-length containers have no length encoded.
+//     For others, the number of bytes is given by pow(2, bd%3)
+//   - maps are encoded as [bd] [length] [[key][value]]...
+//   - arrays are encoded as [bd] [length] [value]...
+//   - extensions are encoded as [bd] [length] [tag] [byte]...
+//   - strings/bytearrays are encoded as [bd] [length] [byte]...
+//   - time.Time are encoded as [bd] [length] [byte]...
+//
+// The full spec will be published soon.
+type SimpleHandle struct {
+	BasicHandle
+	binaryEncodingType
+	noElemSeparators
+	// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
+	EncZeroValuesAsNil bool
+
+	// _ [1]uint64 // padding
+}
+
+// Name returns the name of the handle: simple
+func (h *SimpleHandle) Name() string { return "simple" }
+
+// SetBytesExt sets an extension
+func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
+}
+
+func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
+
+func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
+	return &simpleEncDriver{e: e, w: e.w, h: h}
+}
+
+func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
+	return &simpleDecDriver{d: d, h: h, r: d.r, br: d.bytes}
+}
+
+func (e *simpleEncDriver) reset() {
+	e.c = 0
+	e.w = e.e.w
+}
+
+func (d *simpleDecDriver) reset() {
+	d.c = 0
+	d.r, d.br = d.d.r, d.d.bytes
+	d.bd, d.bdRead = 0, false
+}
+
+var _ decDriver = (*simpleDecDriver)(nil)
+var _ encDriver = (*simpleEncDriver)(nil)
diff --git a/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json b/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
new file mode 100644
index 0000000..9028586
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
@@ -0,0 +1,639 @@
+[
+  {
+    "cbor": "AA==",
+    "hex": "00",
+    "roundtrip": true,
+    "decoded": 0
+  },
+  {
+    "cbor": "AQ==",
+    "hex": "01",
+    "roundtrip": true,
+    "decoded": 1
+  },
+  {
+    "cbor": "Cg==",
+    "hex": "0a",
+    "roundtrip": true,
+    "decoded": 10
+  },
+  {
+    "cbor": "Fw==",
+    "hex": "17",
+    "roundtrip": true,
+    "decoded": 23
+  },
+  {
+    "cbor": "GBg=",
+    "hex": "1818",
+    "roundtrip": true,
+    "decoded": 24
+  },
+  {
+    "cbor": "GBk=",
+    "hex": "1819",
+    "roundtrip": true,
+    "decoded": 25
+  },
+  {
+    "cbor": "GGQ=",
+    "hex": "1864",
+    "roundtrip": true,
+    "decoded": 100
+  },
+  {
+    "cbor": "GQPo",
+    "hex": "1903e8",
+    "roundtrip": true,
+    "decoded": 1000
+  },
+  {
+    "cbor": "GgAPQkA=",
+    "hex": "1a000f4240",
+    "roundtrip": true,
+    "decoded": 1000000
+  },
+  {
+    "cbor": "GwAAAOjUpRAA",
+    "hex": "1b000000e8d4a51000",
+    "roundtrip": true,
+    "decoded": 1000000000000
+  },
+  {
+    "cbor": "G///////////",
+    "hex": "1bffffffffffffffff",
+    "roundtrip": true,
+    "decoded": 18446744073709551615
+  },
+  {
+    "cbor": "wkkBAAAAAAAAAAA=",
+    "hex": "c249010000000000000000",
+    "roundtrip": true,
+    "decoded": 18446744073709551616
+  },
+  {
+    "cbor": "O///////////",
+    "hex": "3bffffffffffffffff",
+    "roundtrip": true,
+    "decoded": -18446744073709551616,
+    "skip": true
+  },
+  {
+    "cbor": "w0kBAAAAAAAAAAA=",
+    "hex": "c349010000000000000000",
+    "roundtrip": true,
+    "decoded": -18446744073709551617
+  },
+  {
+    "cbor": "IA==",
+    "hex": "20",
+    "roundtrip": true,
+    "decoded": -1
+  },
+  {
+    "cbor": "KQ==",
+    "hex": "29",
+    "roundtrip": true,
+    "decoded": -10
+  },
+  {
+    "cbor": "OGM=",
+    "hex": "3863",
+    "roundtrip": true,
+    "decoded": -100
+  },
+  {
+    "cbor": "OQPn",
+    "hex": "3903e7",
+    "roundtrip": true,
+    "decoded": -1000
+  },
+  {
+    "cbor": "+QAA",
+    "hex": "f90000",
+    "roundtrip": true,
+    "decoded": 0.0
+  },
+  {
+    "cbor": "+YAA",
+    "hex": "f98000",
+    "roundtrip": true,
+    "decoded": -0.0
+  },
+  {
+    "cbor": "+TwA",
+    "hex": "f93c00",
+    "roundtrip": true,
+    "decoded": 1.0
+  },
+  {
+    "cbor": "+z/xmZmZmZma",
+    "hex": "fb3ff199999999999a",
+    "roundtrip": true,
+    "decoded": 1.1
+  },
+  {
+    "cbor": "+T4A",
+    "hex": "f93e00",
+    "roundtrip": true,
+    "decoded": 1.5
+  },
+  {
+    "cbor": "+Xv/",
+    "hex": "f97bff",
+    "roundtrip": true,
+    "decoded": 65504.0
+  },
+  {
+    "cbor": "+kfDUAA=",
+    "hex": "fa47c35000",
+    "roundtrip": true,
+    "decoded": 100000.0
+  },
+  {
+    "cbor": "+n9///8=",
+    "hex": "fa7f7fffff",
+    "roundtrip": true,
+    "decoded": 3.4028234663852886e+38
+  },
+  {
+    "cbor": "+3435DyIAHWc",
+    "hex": "fb7e37e43c8800759c",
+    "roundtrip": true,
+    "decoded": 1.0e+300
+  },
+  {
+    "cbor": "+QAB",
+    "hex": "f90001",
+    "roundtrip": true,
+    "decoded": 5.960464477539063e-08
+  },
+  {
+    "cbor": "+QQA",
+    "hex": "f90400",
+    "roundtrip": true,
+    "decoded": 6.103515625e-05
+  },
+  {
+    "cbor": "+cQA",
+    "hex": "f9c400",
+    "roundtrip": true,
+    "decoded": -4.0
+  },
+  {
+    "cbor": "+8AQZmZmZmZm",
+    "hex": "fbc010666666666666",
+    "roundtrip": true,
+    "decoded": -4.1
+  },
+  {
+    "cbor": "+XwA",
+    "hex": "f97c00",
+    "roundtrip": true,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+X4A",
+    "hex": "f97e00",
+    "roundtrip": true,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+fwA",
+    "hex": "f9fc00",
+    "roundtrip": true,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "+n+AAAA=",
+    "hex": "fa7f800000",
+    "roundtrip": false,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+n/AAAA=",
+    "hex": "fa7fc00000",
+    "roundtrip": false,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+v+AAAA=",
+    "hex": "faff800000",
+    "roundtrip": false,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "+3/wAAAAAAAA",
+    "hex": "fb7ff0000000000000",
+    "roundtrip": false,
+    "diagnostic": "Infinity"
+  },
+  {
+    "cbor": "+3/4AAAAAAAA",
+    "hex": "fb7ff8000000000000",
+    "roundtrip": false,
+    "diagnostic": "NaN"
+  },
+  {
+    "cbor": "+//wAAAAAAAA",
+    "hex": "fbfff0000000000000",
+    "roundtrip": false,
+    "diagnostic": "-Infinity"
+  },
+  {
+    "cbor": "9A==",
+    "hex": "f4",
+    "roundtrip": true,
+    "decoded": false
+  },
+  {
+    "cbor": "9Q==",
+    "hex": "f5",
+    "roundtrip": true,
+    "decoded": true
+  },
+  {
+    "cbor": "9g==",
+    "hex": "f6",
+    "roundtrip": true,
+    "decoded": null
+  },
+  {
+    "cbor": "9w==",
+    "hex": "f7",
+    "roundtrip": true,
+    "diagnostic": "undefined"
+  },
+  {
+    "cbor": "8A==",
+    "hex": "f0",
+    "roundtrip": true,
+    "diagnostic": "simple(16)"
+  },
+  {
+    "cbor": "+Bg=",
+    "hex": "f818",
+    "roundtrip": true,
+    "diagnostic": "simple(24)"
+  },
+  {
+    "cbor": "+P8=",
+    "hex": "f8ff",
+    "roundtrip": true,
+    "diagnostic": "simple(255)"
+  },
+  {
+    "cbor": "wHQyMDEzLTAzLTIxVDIwOjA0OjAwWg==",
+    "hex": "c074323031332d30332d32315432303a30343a30305a",
+    "roundtrip": true,
+    "diagnostic": "0(\"2013-03-21T20:04:00Z\")"
+  },
+  {
+    "cbor": "wRpRS2ew",
+    "hex": "c11a514b67b0",
+    "roundtrip": true,
+    "diagnostic": "1(1363896240)"
+  },
+  {
+    "cbor": "wftB1FLZ7CAAAA==",
+    "hex": "c1fb41d452d9ec200000",
+    "roundtrip": true,
+    "diagnostic": "1(1363896240.5)"
+  },
+  {
+    "cbor": "10QBAgME",
+    "hex": "d74401020304",
+    "roundtrip": true,
+    "diagnostic": "23(h'01020304')"
+  },
+  {
+    "cbor": "2BhFZElFVEY=",
+    "hex": "d818456449455446",
+    "roundtrip": true,
+    "diagnostic": "24(h'6449455446')"
+  },
+  {
+    "cbor": "2CB2aHR0cDovL3d3dy5leGFtcGxlLmNvbQ==",
+    "hex": "d82076687474703a2f2f7777772e6578616d706c652e636f6d",
+    "roundtrip": true,
+    "diagnostic": "32(\"http://www.example.com\")"
+  },
+  {
+    "cbor": "QA==",
+    "hex": "40",
+    "roundtrip": true,
+    "diagnostic": "h''"
+  },
+  {
+    "cbor": "RAECAwQ=",
+    "hex": "4401020304",
+    "roundtrip": true,
+    "diagnostic": "h'01020304'"
+  },
+  {
+    "cbor": "YA==",
+    "hex": "60",
+    "roundtrip": true,
+    "decoded": ""
+  },
+  {
+    "cbor": "YWE=",
+    "hex": "6161",
+    "roundtrip": true,
+    "decoded": "a"
+  },
+  {
+    "cbor": "ZElFVEY=",
+    "hex": "6449455446",
+    "roundtrip": true,
+    "decoded": "IETF"
+  },
+  {
+    "cbor": "YiJc",
+    "hex": "62225c",
+    "roundtrip": true,
+    "decoded": "\"\\"
+  },
+  {
+    "cbor": "YsO8",
+    "hex": "62c3bc",
+    "roundtrip": true,
+    "decoded": "ü"
+  },
+  {
+    "cbor": "Y+awtA==",
+    "hex": "63e6b0b4",
+    "roundtrip": true,
+    "decoded": "水"
+  },
+  {
+    "cbor": "ZPCQhZE=",
+    "hex": "64f0908591",
+    "roundtrip": true,
+    "decoded": "𐅑"
+  },
+  {
+    "cbor": "gA==",
+    "hex": "80",
+    "roundtrip": true,
+    "decoded": [
+
+    ]
+  },
+  {
+    "cbor": "gwECAw==",
+    "hex": "83010203",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      2,
+      3
+    ]
+  },
+  {
+    "cbor": "gwGCAgOCBAU=",
+    "hex": "8301820203820405",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=",
+    "hex": "98190102030405060708090a0b0c0d0e0f101112131415161718181819",
+    "roundtrip": true,
+    "decoded": [
+      1,
+      2,
+      3,
+      4,
+      5,
+      6,
+      7,
+      8,
+      9,
+      10,
+      11,
+      12,
+      13,
+      14,
+      15,
+      16,
+      17,
+      18,
+      19,
+      20,
+      21,
+      22,
+      23,
+      24,
+      25
+    ]
+  },
+  {
+    "cbor": "oA==",
+    "hex": "a0",
+    "roundtrip": true,
+    "decoded": {
+    }
+  },
+  {
+    "cbor": "ogECAwQ=",
+    "hex": "a201020304",
+    "roundtrip": true,
+    "skip": true,
+    "diagnostic": "{1: 2, 3: 4}"
+  },
+  {
+    "cbor": "omFhAWFiggID",
+    "hex": "a26161016162820203",
+    "roundtrip": true,
+    "decoded": {
+      "a": 1,
+      "b": [
+        2,
+        3
+      ]
+    }
+  },
+  {
+    "cbor": "gmFhoWFiYWM=",
+    "hex": "826161a161626163",
+    "roundtrip": true,
+    "decoded": [
+      "a",
+      {
+        "b": "c"
+      }
+    ]
+  },
+  {
+    "cbor": "pWFhYUFhYmFCYWNhQ2FkYURhZWFF",
+    "hex": "a56161614161626142616361436164614461656145",
+    "roundtrip": true,
+    "decoded": {
+      "a": "A",
+      "b": "B",
+      "c": "C",
+      "d": "D",
+      "e": "E"
+    }
+  },
+  {
+    "cbor": "X0IBAkMDBAX/",
+    "hex": "5f42010243030405ff",
+    "roundtrip": false,
+    "skip": true,
+    "diagnostic": "(_ h'0102', h'030405')"
+  },
+  {
+    "cbor": "f2VzdHJlYWRtaW5n/w==",
+    "hex": "7f657374726561646d696e67ff",
+    "roundtrip": false,
+    "decoded": "streaming"
+  },
+  {
+    "cbor": "n/8=",
+    "hex": "9fff",
+    "roundtrip": false,
+    "decoded": [
+
+    ]
+  },
+  {
+    "cbor": "nwGCAgOfBAX//w==",
+    "hex": "9f018202039f0405ffff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "nwGCAgOCBAX/",
+    "hex": "9f01820203820405ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "gwGCAgOfBAX/",
+    "hex": "83018202039f0405ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "gwGfAgP/ggQF",
+    "hex": "83019f0203ff820405",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      [
+        2,
+        3
+      ],
+      [
+        4,
+        5
+      ]
+    ]
+  },
+  {
+    "cbor": "nwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBgYGf8=",
+    "hex": "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff",
+    "roundtrip": false,
+    "decoded": [
+      1,
+      2,
+      3,
+      4,
+      5,
+      6,
+      7,
+      8,
+      9,
+      10,
+      11,
+      12,
+      13,
+      14,
+      15,
+      16,
+      17,
+      18,
+      19,
+      20,
+      21,
+      22,
+      23,
+      24,
+      25
+    ]
+  },
+  {
+    "cbor": "v2FhAWFinwID//8=",
+    "hex": "bf61610161629f0203ffff",
+    "roundtrip": false,
+    "decoded": {
+      "a": 1,
+      "b": [
+        2,
+        3
+      ]
+    }
+  },
+  {
+    "cbor": "gmFhv2FiYWP/",
+    "hex": "826161bf61626163ff",
+    "roundtrip": false,
+    "decoded": [
+      "a",
+      {
+        "b": "c"
+      }
+    ]
+  },
+  {
+    "cbor": "v2NGdW71Y0FtdCH/",
+    "hex": "bf6346756ef563416d7421ff",
+    "roundtrip": false,
+    "decoded": {
+      "Fun": true,
+      "Amt": -2
+    }
+  }
+]
diff --git a/vendor/github.com/ugorji/go/codec/test.py b/vendor/github.com/ugorji/go/codec/test.py
new file mode 100755
index 0000000..800376f
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/test.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+
+# This will create golden files in a directory passed to it.
+# A Test calls this internally to create the golden files
+# So it can process them (so we don't have to checkin the files).
+
+# Ensure msgpack-python and cbor are installed first, using:
+#   sudo apt-get install python-dev
+#   sudo apt-get install python-pip
+#   pip install --user msgpack-python msgpack-rpc-python cbor
+
+# Ensure all "string" keys are utf strings (else encoded as bytes)
+
+import cbor, msgpack, msgpackrpc, sys, os, threading
+
+def get_test_data_list():
+    # get list with all primitive types, and a combo type
+    l0 = [ 
+        -8,
+         -1616,
+         -32323232,
+         -6464646464646464,
+         192,
+         1616,
+         32323232,
+         6464646464646464,
+         192,
+         -3232.0,
+         -6464646464.0,
+         3232.0,
+         6464.0,
+         6464646464.0,
+         False,
+         True,
+         u"null",
+         None,
+         u"some&day>some<day",
+         1328176922000002000,
+         u"",
+         -2206187877999998000,
+         u"bytestring",
+         270,
+         u"none",
+        -2013855847999995777,
+         #-6795364578871345152,
+         ]
+    l1 = [
+        { "true": True,
+          "false": False },
+        { "true": u"True",
+          "false": False,
+          "uint16(1616)": 1616 },
+        { "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ],
+          "int32":32323232, "bool": True, 
+          "LONG STRING": u"123456789012345678901234567890123456789012345678901234567890",
+          "SHORT STRING": u"1234567890" },
+        { True: "true", 138: False, "false": 200 }
+        ]
+    
+    l = []
+    l.extend(l0)
+    l.append(l0)
+    l.append(1)
+    l.extend(l1)
+    return l
+
+def build_test_data(destdir):
+    l = get_test_data_list()
+    for i in range(len(l)):
+        # packer = msgpack.Packer()
+        serialized = msgpack.dumps(l[i])
+        f = open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb')
+        f.write(serialized)
+        f.close()
+        serialized = cbor.dumps(l[i])
+        f = open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb')
+        f.write(serialized)
+        f.close()
+
+def doRpcServer(port, stopTimeSec):
+    class EchoHandler(object):
+        def Echo123(self, msg1, msg2, msg3):
+            return ("1:%s 2:%s 3:%s" % (msg1, msg2, msg3))
+        def EchoStruct(self, msg):
+            return ("%s" % msg)
+    
+    addr = msgpackrpc.Address('127.0.0.1', port)
+    server = msgpackrpc.Server(EchoHandler())
+    server.listen(addr)
+    # run thread to stop it after stopTimeSec seconds if > 0
+    if stopTimeSec > 0:
+        def myStopRpcServer():
+            server.stop()
+        t = threading.Timer(stopTimeSec, myStopRpcServer)
+        t.start()
+    server.start()
+
+def doRpcClientToPythonSvc(port):
+    address = msgpackrpc.Address('127.0.0.1', port)
+    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
+    print client.call("Echo123", "A1", "B2", "C3")
+    print client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
+   
+def doRpcClientToGoSvc(port):
+    # print ">>>> port: ", port, " <<<<<"
+    address = msgpackrpc.Address('127.0.0.1', port)
+    client = msgpackrpc.Client(address, unpack_encoding='utf-8')
+    print client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"])
+    print client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
+
+def doMain(args):
+    if len(args) == 2 and args[0] == "testdata":
+        build_test_data(args[1])
+    elif len(args) == 3 and args[0] == "rpc-server":
+        doRpcServer(int(args[1]), int(args[2]))
+    elif len(args) == 2 and args[0] == "rpc-client-python-service":
+        doRpcClientToPythonSvc(int(args[1]))
+    elif len(args) == 2 and args[0] == "rpc-client-go-service":
+        doRpcClientToGoSvc(int(args[1]))
+    else:
+        print("Usage: test.py " + 
+              "[testdata|rpc-server|rpc-client-python-service|rpc-client-go-service] ...")
+    
+if __name__ == "__main__":
+    doMain(sys.argv[1:])
+
diff --git a/vendor/github.com/ugorji/go/codec/xml.go b/vendor/github.com/ugorji/go/codec/xml.go
new file mode 100644
index 0000000..19fc36c
--- /dev/null
+++ b/vendor/github.com/ugorji/go/codec/xml.go
@@ -0,0 +1,508 @@
+// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a MIT license found in the LICENSE file.
+
+// +build ignore
+
+package codec
+
+import "reflect"
+
+/*
+
+A strict Non-validating namespace-aware XML 1.0 parser and (en|de)coder.
+
+We are attempting this due to perceived issues with encoding/xml:
+  - Complicated. It tried to do too much, and is not as simple to use as json.
+  - Due to over-engineering, reflection is over-used AND performance suffers:
+    java is 6X faster:http://fabsk.eu/blog/category/informatique/dev/golang/
+    even PYTHON performs better: http://outgoing.typepad.com/outgoing/2014/07/exploring-golang.html
+
+codec framework will offer the following benefits
+  - VASTLY improved performance (when using reflection-mode or codecgen)
+  - simplicity and consistency: with the rest of the supported formats
+  - all other benefits of codec framework (streaming, codegeneration, etc)
+
+codec is not a drop-in replacement for encoding/xml.
+It is a replacement, based on the simplicity and performance of codec.
+Look at it like JAXB for Go.
+
+Challenges:
+  - Need to output XML preamble, with all namespaces at the right location in the output.
+  - Each "end" block is dynamic, so we need to maintain a context-aware stack
+  - How to decide when to use an attribute VS an element
+  - How to handle chardata, attr, comment EXPLICITLY.
+  - Should it output fragments?
+    e.g. encoding a bool should just output true OR false, which is not well-formed XML.
+
+Extend the struct tag. See representative example:
+  type X struct {
+    ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
+    // format: [namespace-uri ][namespace-prefix ]local-name, ...
+  }
+
+Based on this, we encode
+  - fields as elements, BUT
+    encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
+  - text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
+
+To handle namespaces:
+  - XMLHandle is denoted as being namespace-aware.
+    Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
+  - *Encoder and *Decoder know whether the Handle "prefers" namespaces.
+  - add *Encoder.getEncName(*structFieldInfo).
+    No one calls *structFieldInfo.indexForEncName directly anymore
+  - OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
+    indexForEncName takes a parameter of the form namespace:local-name OR local-name
+  - add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
+    by being a method on *Decoder, or maybe a method on the Handle itself.
+    No one accesses .encName anymore
+  - let encode.go and decode.go use these (for consistency)
+  - only problem exists for gen.go, where we create a big switch on encName.
+    Now, we also have to add a switch on strings.endsWith(kName, encNsName)
+    - gen.go will need to have many more methods, and then double-on the 2 switch loops like:
+      switch k {
+        case "abc" : x.abc()
+        case "def" : x.def()
+        default {
+          switch {
+            case !nsAware: panic(...)
+            case strings.endsWith(":abc"): x.abc()
+            case strings.endsWith(":def"): x.def()
+            default: panic(...)
+          }
+        }
+     }
+
+The structure below accommodates this:
+
+  type typeInfo struct {
+    sfi []*structFieldInfo // sorted by encName
+    sfins // sorted by namespace
+    sfia  // sorted, to have those with attributes at the top. Needed to write XML appropriately.
+    sfip  // unsorted
+  }
+  type structFieldInfo struct {
+    encName
+    nsEncName
+    ns string
+    attr bool
+    cdata bool
+  }
+
+indexForEncName is now an internal helper function that takes a sorted array
+(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
+
+There will be a separate parser from the builder.
+The parser will have a method: next() xmlToken method. It has lookahead support,
+so you can pop multiple tokens, make a determination, and push them back in the order popped.
+This will be needed to determine whether we are "nakedly" decoding a container or not.
+The stack will be implemented using a slice and push/pop happens at the [0] element.
+
+xmlToken has fields:
+  - type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
+  - value string
+  - ns string
+
+SEE: http://www.xml.com/pub/a/98/10/guide0.html?page=3#ENTDECL
+
+The following are skipped when parsing:
+  - External Entities (from external file)
+  - Notation Declaration e.g. <!NOTATION GIF87A SYSTEM "GIF">
+  - Entity Declarations & References
+  - XML Declaration (assume UTF-8)
+  - XML Directive i.e. <! ... >
+  - Other Declarations: Notation, etc.
+  - Comment
+  - Processing Instruction
+  - schema / DTD for validation:
+    We are not a VALIDATING parser. Validation is done elsewhere.
+    However, some parts of the DTD internal subset are used (SEE BELOW).
+    For Attribute List Declarations e.g.
+    <!ATTLIST foo:oldjoke name ID #REQUIRED label CDATA #IMPLIED status ( funny | notfunny ) 'funny' >
+    We considered using the ATTLIST to get "default" value, but not to validate the contents. (VETOED)
+
+The following XML features are supported
+  - Namespace
+  - Element
+  - Attribute
+  - cdata
+  - Unicode escape
+
+The following DTD (when as an internal sub-set) features are supported:
+  - Internal Entities e.g.
+    <!ELEMENT burns "ugorji is cool" > AND entities for the set: [<>&"']
+  - Parameter entities e.g.
+    <!ENTITY % personcontent "ugorji is cool"> <!ELEMENT burns (%personcontent;)*>
+
+At decode time, a structure containing the following is kept
+  - namespace mapping
+  - default attribute values
+  - all internal entities (<>&"' and others written in the document)
+
+When decode starts, it parses XML namespace declarations and creates a map in the
+xmlDecDriver. While parsing, that map continuously gets updated.
+The only problem happens when a namespace declaration happens on the node that it defines.
+e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
+To handle this, each Element must be fully parsed at a time,
+even if it amounts to multiple tokens which are returned one at a time on request.
+
+xmlns is a special attribute name.
+  - It is used to define namespaces, including the default
+  - It is never returned as an AttrKey or AttrVal.
+  *We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
+
+Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
+This accommodates map[int]string for example.
+
+It should be possible to create a schema from the types,
+or vice versa (generate types from schema with appropriate tags).
+This is however out-of-scope from this parsing project.
+
+We should write all namespace information at the first point that it is referenced in the tree,
+and use the mapping for all child nodes and attributes. This means that state is maintained
+at a point in the tree. This also means that calls to Decode or MustDecode will reset some state.
+
+When decoding, it is important to keep track of entity references and default attribute values.
+It seems these can only be stored in the DTD components. We should honor them when decoding.
+
+Configuration for XMLHandle will look like this:
+
+  XMLHandle
+    DefaultNS string
+    // Encoding:
+    NS map[string]string // ns URI to key, used for encoding
+    // Decoding: in case ENTITY declared in external schema or dtd, store info needed here
+    Entities map[string]string // map of entity rep to character
+
+
+During encode, if a namespace mapping is not defined for a namespace found on a struct,
+then we create a mapping for it using nsN (where N is 1..1000000, and doesn't conflict
+with any other namespace mapping).
+
+Note that different fields in a struct can have different namespaces.
+However, all fields will default to the namespace on the _struct field (if defined).
+
+An XML document is a name, a map of attributes and a list of children.
+Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
+We have to "DecodeNaked" into something that resembles XML data.
+
+To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
+    type Name struct { // Preferred. Less allocations due to conversions.
+      Local string
+      Space string
+    }
+    type Element struct {
+      Name Name
+      Attrs map[Name]string
+      Children []interface{} // each child is either *Element or string
+    }
+Only two "supporting" types are exposed for XML: Name and Element.
+
+// ------------------
+
+We considered 'type Name string' where Name is like "Space Local" (space-separated).
+We decided against it, because each creation of a name would lead to
+double allocation (first convert []byte to string, then concatenate them into a string).
+The benefit is that it is faster to read Attrs from a map. But given that Element is a value
+object, we want to eschew methods and have public exposed variables.
+
+We also considered the following, where xml types were not value objects, and we used
+intelligent accessor methods to extract information and for performance.
+*** WE DECIDED AGAINST THIS. ***
+    type Attr struct {
+      Name Name
+      Value string
+    }
+    // Element is a ValueObject: There are no accessor methods.
+    // Make element self-contained.
+    type Element struct {
+      Name Name
+      attrsMap map[string]string // where key is "Space Local"
+      attrs []Attr
+      childrenT []string
+      childrenE []Element
+      childrenI []int // each child is a index into T or E.
+    }
+    func (x *Element) child(i) interface{} // returns string or *Element
+
+// ------------------
+
+Per XML spec and our default handling, white space is always treated as
+insignificant between elements, except in a text node. The xml:space='preserve'
+attribute is ignored.
+
+**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
+**So treat them as just "directives" that should be interpreted to mean something**.
+
+On encoding, we support indenting aka prettifying markup in the same way we support it for json.
+
+A document or element can only be encoded/decoded from/to a struct. In this mode:
+  - struct name maps to element name (or tag-info from _struct field)
+  - fields are mapped to child elements or attributes
+
+A map is either encoded as attributes on current element, or as a set of child elements.
+Maps are encoded as attributes iff their keys and values are primitives (number, bool, string).
+
+A list is encoded as a set of child elements.
+
+Primitives (number, bool, string) are encoded as an element, attribute or text
+depending on the context.
+
+Extensions must encode themselves as a text string.
+
+Encoding is tough, specifically when encoding mappings, because we need to encode
+as either attribute or element. To do this, we need to default to encoding as attributes,
+and then let Encoder inform the Handle when to start encoding as nodes.
+i.e. Encoder does something like:
+
+    h.EncodeMapStart()
+    h.Encode(), h.Encode(), ...
+    h.EncodeMapNotAttrSignal() // this is not a bool, because it's a signal
+    h.Encode(), h.Encode(), ...
+    h.EncodeEnd()
+
+Only XMLHandle understands this, and will set itself to start encoding as elements.
+
+This support extends to maps. For example, if a struct field is a map, and it has
+the struct tag signifying it should be attr, then all its fields are encoded as attributes.
+e.g.
+
+    type X struct {
+       M map[string]int `codec:"m,attr"` // encode keys as attributes named
+    }
+
+Question:
+  - if encoding a map, what if map keys have spaces in them???
+    Then they cannot be attributes or child elements. Error.
+
+Options to consider adding later:
+  - For attribute values, normalize by trimming beginning and ending white space,
+    and converting every white space sequence to a single space.
+  - ATTLIST restrictions are enforced.
+    e.g. default value of xml:space, skipping xml:XYZ style attributes, etc.
+  - Consider supporting NON-STRICT mode (e.g. to handle HTML parsing).
+    Some elements e.g. br, hr, etc need not close and should be auto-closed
+    ... (see http://www.w3.org/TR/html4/loose.dtd)
+    An expansive set of entities are pre-defined.
+  - Have easy way to create a HTML parser:
+    add a HTML() method to XMLHandle, that will set Strict=false, specify AutoClose,
+    and add HTML Entities to the list.
+  - Support validating element/attribute XMLName before writing it.
+    Keep this behind a flag, which is set to false by default (for performance).
+    type XMLHandle struct {
+      CheckName bool
+    }
+
+Misc:
+
+ROADMAP (1 weeks):
+  - build encoder (1 day)
+  - build decoder (based off xmlParser) (1 day)
+  - implement xmlParser (2 days).
+    Look at encoding/xml for inspiration.
+  - integrate and TEST (1 days)
+  - write article and post it (1 day)
+
+// ---------- MORE NOTES FROM 2017-11-30 ------------
+
+when parsing
+- parse the attributes first
+- then parse the nodes
+
+basically:
+- if encoding a field: we use the field name for the wrapper
+- if encoding a non-field, then just use the element type name
+
+  map[string]string ==> <map><key>abc</key><value>val</value></map>... or
+                        <map key="abc">val</map>... OR
+                        <key1>val1</key1><key2>val2</key2>...                <- PREFERED
+  []string  ==> <string>v1</string><string>v2</string>...
+  string v1 ==> <string>v1</string>
+  bool true ==> <bool>true</bool>
+  float 1.0 ==> <float>1.0</float>
+  ...
+
+  F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
+                           <F1 key="abc">val</F1>... OR
+                           <F1><abc>val</abc>...</F1>                        <- PREFERED
+  F2 []string          ==> <F2>v1</F2><F2>v2</F2>...
+  F3 bool              ==> <F3>true</F3>
+  ...
+
+- a scalar is encoded as:
+  (value) of type T  ==> <T><value/></T>
+  (value) of field F ==> <F><value/></F>
+- A kv-pair is encoded as:
+  (key,value) ==> <map><key><value/></key></map> OR <map key="value">
+  (key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
+- A map or struct is just a list of kv-pairs
+- A list is encoded as sequences of same node e.g.
+  <F1 key1="value11">
+  <F1 key2="value12">
+  <F2>value21</F2>
+  <F2>value22</F2>
+- we may have to singularize the field name, when entering into xml,
+  and pluralize them when encoding.
+- bi-directional encode->decode->encode is not a MUST.
+  even encoding/xml cannot decode correctly what was encoded:
+
+  see https://play.golang.org/p/224V_nyhMS
+  func main() {
+	fmt.Println("Hello, playground")
+	v := []interface{}{"hello", 1, true, nil, time.Now()}
+	s, err := xml.Marshal(v)
+	fmt.Printf("err: %v, \ns: %s\n", err, s)
+	var v2 []interface{}
+	err = xml.Unmarshal(s, &v2)
+	fmt.Printf("err: %v, \nv2: %v\n", err, v2)
+	type T struct {
+	    V []interface{}
+	}
+	v3 := T{V: v}
+	s, err = xml.Marshal(v3)
+	fmt.Printf("err: %v, \ns: %s\n", err, s)
+	var v4 T
+	err = xml.Unmarshal(s, &v4)
+	fmt.Printf("err: %v, \nv4: %v\n", err, v4)
+  }
+  Output:
+    err: <nil>,
+    s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
+    err: <nil>,
+    v2: [<nil>]
+    err: <nil>,
+    s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
+    err: <nil>,
+    v4: {[<nil> <nil> <nil> <nil>]}
+-
+*/
+
+// ----------- PARSER  -------------------
+
+type xmlTokenType uint8
+
+const (
+	_ xmlTokenType = iota << 1
+	xmlTokenElemStart
+	xmlTokenElemEnd
+	xmlTokenAttrKey
+	xmlTokenAttrVal
+	xmlTokenText
+)
+
+type xmlToken struct {
+	Type      xmlTokenType
+	Value     string
+	Namespace string // blank for AttrVal and Text
+}
+
+type xmlParser struct {
+	r    decReader
+	toks []xmlToken // list of tokens.
+	ptr  int        // ptr into the toks slice
+	done bool       // nothing else to parse. r now returns EOF.
+}
+
+func (x *xmlParser) next() (t *xmlToken) {
+	// once x.done, or x.ptr == len(x.toks) == 0, then return nil (to signify finish)
+	if !x.done && len(x.toks) == 0 {
+		x.nextTag()
+	}
+	// parses one element at a time (into possible many tokens)
+	if x.ptr < len(x.toks) {
+		t = &(x.toks[x.ptr])
+		x.ptr++
+		if x.ptr == len(x.toks) {
+			x.ptr = 0
+			x.toks = x.toks[:0]
+		}
+	}
+	return
+}
+
+// nextTag will parses the next element and fill up toks.
+// It set done flag if/once EOF is reached.
+func (x *xmlParser) nextTag() {
+	// TODO: implement.
+}
+
+// ----------- ENCODER -------------------
+
+type xmlEncDriver struct {
+	e  *Encoder
+	w  encWriter
+	h  *XMLHandle
+	b  [64]byte // scratch
+	bs []byte   // scratch
+	// s  jsonStack
+	noBuiltInTypes
+}
+
+// ----------- DECODER -------------------
+
+type xmlDecDriver struct {
+	d    *Decoder
+	h    *XMLHandle
+	r    decReader // *bytesDecReader decReader
+	ct   valueType // container type. one of unset, array or map.
+	bstr [8]byte   // scratch used for string \UXXX parsing
+	b    [64]byte  // scratch
+
+	// wsSkipped bool // whitespace skipped
+
+	// s jsonStack
+
+	noBuiltInTypes
+}
+
+// DecodeNaked will decode into an XMLNode
+
+// XMLName is a value object representing a namespace-aware NAME
+type XMLName struct {
+	Local string
+	Space string
+}
+
+// XMLNode represents a "union" of the different types of XML Nodes.
+// Only one of fields (Text or *Element) is set.
+type XMLNode struct {
+	Element *Element
+	Text    string
+}
+
+// XMLElement is a value object representing an fully-parsed XML element.
+type XMLElement struct {
+	Name  Name
+	Attrs map[XMLName]string
+	// Children is a list of child nodes, each being a *XMLElement or string
+	Children []XMLNode
+}
+
+// ----------- HANDLE  -------------------
+
+type XMLHandle struct {
+	BasicHandle
+	textEncodingType
+
+	DefaultNS string
+	NS        map[string]string // ns URI to key, for encoding
+	Entities  map[string]string // entity representation to string, for encoding.
+}
+
+func (h *XMLHandle) newEncDriver(e *Encoder) encDriver {
+	return &xmlEncDriver{e: e, w: e.w, h: h}
+}
+
+func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
+	// d := xmlDecDriver{r: r.(*bytesDecReader), h: h}
+	hd := xmlDecDriver{d: d, r: d.r, h: h}
+	hd.n.bytes = d.b[:]
+	return &hd
+}
+
+func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
+	return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
+}
+
+var _ decDriver = (*xmlDecDriver)(nil)
+var _ encDriver = (*xmlEncDriver)(nil)