func PMapIntUint64Ptr(f func(*int) *uint64, list []*int, optional ...Optional) []*uint64 {
	if f == nil {
		return []*uint64{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntUint64PtrNoOrder(f, list, worker)
		}
	}
	return pMapIntUint64PtrPreserveOrder(f, list, worker)
}
PMapIntUint64Ptr applies the function(1st argument) on each item in the list and returns a new list.
Order of new list is guaranteed. This feature can be disabled by passing: Optional{RandomOrder: true} to gain performance
Run in parallel. no_of_goroutines = no_of_items_in_list or 3rd argument can be passed to fix the number of goroutines.

Takes 3 inputs. 3rd argument is optional
1. Function - takes 1 input
2. List
3. optional argument - fp.Optional{FixedPool: <some_number>}
package fp
import "sync"
func PMapIntInt64Ptr(f func(*int) *int64, list []*int, optional ...Optional) []*int64 {
	if f == nil {
		return []*int64{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntInt64PtrNoOrder(f, list, worker)
		}
	}
	return pMapIntInt64PtrPreserveOrder(f, list, worker)
}
func pMapIntInt64PtrPreserveOrder(f func(*int) *int64, list []*int, worker int) []*int64 {
	chJobs := make(chan map[int]*int, len(list))
	go func() {
		for i, v := range list {
			chJobs <- map[int]*int{i: v}
		}
		close(chJobs)
	}()
	chResult := make(chan map[int]*int64, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan map[int]*int64, chJobs chan map[int]*int) {
			defer wg.Done()
			for m := range chJobs {
				for k, v := range m {
					chResult <- map[int]*int64{k: f(v)}
				}
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newListMap := make(map[int]*int64, len(list))
	newList := make([]*int64, len(list))
	for m := range chResult {
		for k, v := range m {
			newListMap[k] = v
		}
	}
	for i := 0; i < len(list); i++ {
		newList[i] = newListMap[i]
	}
	return newList
}
func pMapIntInt64PtrNoOrder(f func(*int) *int64, list []*int, worker int) []*int64 {
	chJobs := make(chan *int, len(list))
	go func() {
		for _, v := range list {
			chJobs <- v
		}
		close(chJobs)
	}()
	chResult := make(chan *int64, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan *int64, chJobs chan *int) {
			defer wg.Done()
			for v := range chJobs {
				chResult <- f(v)
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newList := make([]*int64, len(list))
	i := 0
	for v := range chResult {
		newList[i] = v
		i++
	}
	return newList
}
func PMapIntInt32Ptr(f func(*int) *int32, list []*int, optional ...Optional) []*int32 {
	if f == nil {
		return []*int32{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntInt32PtrNoOrder(f, list, worker)
		}
	}
	return pMapIntInt32PtrPreserveOrder(f, list, worker)
}
func pMapIntInt32PtrPreserveOrder(f func(*int) *int32, list []*int, worker int) []*int32 {
	chJobs := make(chan map[int]*int, len(list))
	go func() {
		for i, v := range list {
			chJobs <- map[int]*int{i: v}
		}
		close(chJobs)
	}()
	chResult := make(chan map[int]*int32, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan map[int]*int32, chJobs chan map[int]*int) {
			defer wg.Done()
			for m := range chJobs {
				for k, v := range m {
					chResult <- map[int]*int32{k: f(v)}
				}
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newListMap := make(map[int]*int32, len(list))
	newList := make([]*int32, len(list))
	for m := range chResult {
		for k, v := range m {
			newListMap[k] = v
		}
	}
	for i := 0; i < len(list); i++ {
		newList[i] = newListMap[i]
	}
	return newList
}
func pMapIntInt32PtrNoOrder(f func(*int) *int32, list []*int, worker int) []*int32 {
	chJobs := make(chan *int, len(list))
	go func() {
		for _, v := range list {
			chJobs <- v
		}
		close(chJobs)
	}()
	chResult := make(chan *int32, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan *int32, chJobs chan *int) {
			defer wg.Done()
			for v := range chJobs {
				chResult <- f(v)
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newList := make([]*int32, len(list))
	i := 0
	for v := range chResult {
		newList[i] = v
		i++
	}
	return newList
}
func PMapIntInt16Ptr(f func(*int) *int16, list []*int, optional ...Optional) []*int16 {
	if f == nil {
		return []*int16{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntInt16PtrNoOrder(f, list, worker)
		}
	}
	return pMapIntInt16PtrPreserveOrder(f, list, worker)
}
func pMapIntInt16PtrPreserveOrder(f func(*int) *int16, list []*int, worker int) []*int16 {
	chJobs := make(chan map[int]*int, len(list))
	go func() {
		for i, v := range list {
			chJobs <- map[int]*int{i: v}
		}
		close(chJobs)
	}()
	chResult := make(chan map[int]*int16, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan map[int]*int16, chJobs chan map[int]*int) {
			defer wg.Done()
			for m := range chJobs {
				for k, v := range m {
					chResult <- map[int]*int16{k: f(v)}
				}
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newListMap := make(map[int]*int16, len(list))
	newList := make([]*int16, len(list))
	for m := range chResult {
		for k, v := range m {
			newListMap[k] = v
		}
	}
	for i := 0; i < len(list); i++ {
		newList[i] = newListMap[i]
	}
	return newList
}
func pMapIntInt16PtrNoOrder(f func(*int) *int16, list []*int, worker int) []*int16 {
	chJobs := make(chan *int, len(list))
	go func() {
		for _, v := range list {
			chJobs <- v
		}
		close(chJobs)
	}()
	chResult := make(chan *int16, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan *int16, chJobs chan *int) {
			defer wg.Done()
			for v := range chJobs {
				chResult <- f(v)
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newList := make([]*int16, len(list))
	i := 0
	for v := range chResult {
		newList[i] = v
		i++
	}
	return newList
}
func PMapIntInt8Ptr(f func(*int) *int8, list []*int, optional ...Optional) []*int8 {
	if f == nil {
		return []*int8{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntInt8PtrNoOrder(f, list, worker)
		}
	}
	return pMapIntInt8PtrPreserveOrder(f, list, worker)
}
func pMapIntInt8PtrPreserveOrder(f func(*int) *int8, list []*int, worker int) []*int8 {
	chJobs := make(chan map[int]*int, len(list))
	go func() {
		for i, v := range list {
			chJobs <- map[int]*int{i: v}
		}
		close(chJobs)
	}()
	chResult := make(chan map[int]*int8, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan map[int]*int8, chJobs chan map[int]*int) {
			defer wg.Done()
			for m := range chJobs {
				for k, v := range m {
					chResult <- map[int]*int8{k: f(v)}
				}
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newListMap := make(map[int]*int8, len(list))
	newList := make([]*int8, len(list))
	for m := range chResult {
		for k, v := range m {
			newListMap[k] = v
		}
	}
	for i := 0; i < len(list); i++ {
		newList[i] = newListMap[i]
	}
	return newList
}
func pMapIntInt8PtrNoOrder(f func(*int) *int8, list []*int, worker int) []*int8 {
	chJobs := make(chan *int, len(list))
	go func() {
		for _, v := range list {
			chJobs <- v
		}
		close(chJobs)
	}()
	chResult := make(chan *int8, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan *int8, chJobs chan *int) {
			defer wg.Done()
			for v := range chJobs {
				chResult <- f(v)
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newList := make([]*int8, len(list))
	i := 0
	for v := range chResult {
		newList[i] = v
		i++
	}
	return newList
}
func PMapIntUintPtr(f func(*int) *uint, list []*int, optional ...Optional) []*uint {
	if f == nil {
		return []*uint{}
	}
	var worker = len(list)
	if optional != nil && len(optional) > 0 {
		if optional[0].FixedPool > 0 && optional[0].FixedPool < worker {
			worker = optional[0].FixedPool
		}
		if optional[0].RandomOrder == true {
			return pMapIntUintPtrNoOrder(f, list, worker)
		}
	}
	return pMapIntUintPtrPreserveOrder(f, list, worker)
}
func pMapIntUintPtrPreserveOrder(f func(*int) *uint, list []*int, worker int) []*uint {
	chJobs := make(chan map[int]*int, len(list))
	go func() {
		for i, v := range list {
			chJobs <- map[int]*int{i: v}
		}
		close(chJobs)
	}()
	chResult := make(chan map[int]*uint, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan map[int]*uint, chJobs chan map[int]*int) {
			defer wg.Done()
			for m := range chJobs {
				for k, v := range m {
					chResult <- map[int]*uint{k: f(v)}
				}
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newListMap := make(map[int]*uint, len(list))
	newList := make([]*uint, len(list))
	for m := range chResult {
		for k, v := range m {
			newListMap[k] = v
		}
	}
	for i := 0; i < len(list); i++ {
		newList[i] = newListMap[i]
	}
	return newList
}
func pMapIntUintPtrNoOrder(f func(*int) *uint, list []*int, worker int) []*uint {
	chJobs := make(chan *int, len(list))
	go func() {
		for _, v := range list {
			chJobs <- v
		}
		close(chJobs)
	}()
	chResult := make(chan *uint, worker/3)
	var wg sync.WaitGroup
	for i := 0; i < worker; i++ {
		wg.Add(1)
		go func(chResult chan *uint, chJobs chan *int) {
			defer wg.Done()
			for v := range chJobs {
				chResult <- f(v)
			}
		}(chResult, chJobs)
	}
	go func() {
		wg.Wait()
		close(chResult)
	}()
	newList := make([]*uint, len(list))
	i := 0
	for v := range chResult {
		newList[i] = v
		i++
	}
	return newList
}