func (em *EnumMap) ForEachSorted(f func(k int, v string)) {
	if em == nil || len(em.asString) == 0 {
		return
	}
	for _, k := range em.sortedIntKeys() {
		f(k, em.asString[k])
	}
}
ForEachSorted execute function for each enum with strict ordering
this is somewhat heavier than using regular ForEach
package enummap
import (
	"fmt"
	"sort"
	"strings"
	jsoniter "github.com/json-iterator/go"
	"github.com/pkg/errors"
)
type (
	EnumMap struct {
		asString map[int]string
		asInt    map[string]int
	}
	IntKeyNotFoundError int
	StringKeyNotFoundError string
	DuplicateValueError int
	DuplicateKeyError string
	NonLowercaseKeyError string
)
var jsonit = jsoniter.ConfigCompatibleWithStandardLibrary
func (ik IntKeyNotFoundError) Error() string {
	return fmt.Sprintf("Key<%d> not found", int(ik))
}
func (sk StringKeyNotFoundError) Error() string {
	return fmt.Sprintf("Key<%s> not found", string(sk))
}
func (dv DuplicateValueError) Error() string {
	return fmt.Sprintf("Value<%d> is duplicated", int(dv))
}
func (dk DuplicateKeyError) Error() string {
	return fmt.Sprintf("Key<%s> is duplicated", string(dk))
}
func (nlk NonLowercaseKeyError) Error() string {
	return fmt.Sprintf("Key<%s> must use lowercase characters only", string(nlk))
}
func New() *EnumMap {
	em := &EnumMap{
		asInt:    make(map[string]int),
		asString: make(map[int]string),
	}
	return em
}
func NewEnumMap(m map[string]int) (*EnumMap, error) {
	em := &EnumMap{
		asInt: m,
	}
	em.asString = make(map[int]string, len(m))
	for k, v := range m {
		if _, ok := em.asString[v]; ok {
			return nil, DuplicateValueError(v)
		}
		if strings.ToLower(k) != k {
			return nil, NonLowercaseKeyError(k)
		}
		em.asString[v] = k
	}
	return em, nil
}
func NewEnumMapOrPanic(m map[string]int) *EnumMap {
	enumMap, err := NewEnumMap(m)
	if err != nil {
		panic(fmt.Errorf("Invalid EnumMap: %s", err))
	}
	return enumMap
}
func (em *EnumMap) AsInt() map[string]int {
	return em.asInt
}
func (em *EnumMap) Int(s string) (int, error) {
	i, ok := em.asInt[strings.ToLower(s)]
	if !ok {
		return 0, StringKeyNotFoundError(s)
	}
	return i, nil
}
func (em *EnumMap) String(i int) (string, error) {
	s, ok := em.asString[i]
	if !ok {
		return "", IntKeyNotFoundError(i)
	}
	return s, nil
}
func (em *EnumMap) StringDefault(i int, dflt string) string {
	s, ok := em.asString[i]
	if !ok {
		return dflt
	}
	return s
}
func (em *EnumMap) Add(k string, v int) error {
	if k == "" {
		return fmt.Errorf("key is empty")
	}
	k = strings.ToLower(k)
	if _, ok := em.asString[v]; ok {
		return DuplicateValueError(v)
	}
	if _, ok := em.asInt[k]; ok {
		return DuplicateKeyError(k)
	}
	em.asInt[k] = v
	em.asString[v] = k
	return nil
}
func (em *EnumMap) UnMarshal(arg []byte) (int, error) {
	var i int
	if err := jsonit.Unmarshal(arg, &i); err == nil {
		return i, nil
	}
	var s string
	if err := jsonit.Unmarshal(arg, &s); err != nil {
		return 0, errors.Wrapf(err, "Failed to unmarshal byte array<%v>", arg)
	}
	i, err := em.Int(strings.ToLower(s))
	if err != nil {
		return 0, errors.Wrapf(err, "Unknown enum<%s>", s)
	}
	return i, nil
}
func (em *EnumMap) ForEach(f func(k int, v string)) {
	if em == nil || len(em.asString) == 0 {
		return
	}
	for k, v := range em.asString {
		f(k, v)
	}
}