From 2be84c7e2facda6ece682f80b5c71d7bbd5a103d Mon Sep 17 00:00:00 2001 From: andeya Date: Mon, 27 Jun 2022 01:15:49 +0800 Subject: [PATCH] chore: rename mod, update go.mod --- LICENSE | 2 +- README.md | 14 +- README_ZH.md | 14 +- agent.go | 2 +- body.go | 4 +- example/example001/example.go | 3 +- example/example002/example.go | 9 +- example/example003/example.go | 7 +- example/example004/example.go | 9 +- example/example005/example.go | 11 +- go.mod | 14 +- go.sum | 24 +- phantom.go | 14 +- request.go | 2 +- surf.go | 4 +- surfer.go | 8 +- surfer_test.go | 2 +- util.go | 2 +- .../{henrylee2cn => andeya}/goutil/.gitignore | 3 + .../goutil/.travis.yml | 2 +- vendor/github.com/andeya/goutil/LICENSE | 21 + vendor/github.com/andeya/goutil/README.md | 9 + .../{henrylee2cn => andeya}/goutil/currip.go | 6 +- .../{henrylee2cn => andeya}/goutil/doc.go | 0 vendor/github.com/andeya/goutil/encrypt.go | 274 ++ .../{henrylee2cn => andeya}/goutil/file.go | 0 .../{henrylee2cn => andeya}/goutil/gopath.go | 0 vendor/github.com/andeya/goutil/gotest.go | 41 + .../{henrylee2cn => andeya}/goutil/js_url.go | 0 .../{henrylee2cn => andeya}/goutil/kvdata.go | 0 .../{henrylee2cn => andeya}/goutil/map.go | 16 +- .../{henrylee2cn => andeya}/goutil/other.go | 14 + .../goutil/pid_file.go | 0 .../{henrylee2cn => andeya}/goutil/random.go | 41 +- vendor/github.com/andeya/goutil/sets.go | 233 ++ .../{henrylee2cn => andeya}/goutil/string.go | 132 +- .../{henrylee2cn => andeya}/goutil/targz.go | 0 .../{henrylee2cn => andeya}/goutil/trace.go | 0 .../exported.go => andeya/goutil/type.go} | 22 + .../github.com/henrylee2cn/ameda/.gitignore | 21 + vendor/github.com/henrylee2cn/ameda/LICENSE | 21 + vendor/github.com/henrylee2cn/ameda/README.md | 3 + vendor/github.com/henrylee2cn/ameda/atoi62.go | 253 ++ vendor/github.com/henrylee2cn/ameda/atoi_x.go | 27 + vendor/github.com/henrylee2cn/ameda/bool.go | 200 + vendor/github.com/henrylee2cn/ameda/bools.go | 580 +++ .../github.com/henrylee2cn/ameda/float32.go | 217 + .../github.com/henrylee2cn/ameda/float32s.go | 680 ++++ .../github.com/henrylee2cn/ameda/float64.go | 220 ++ .../github.com/henrylee2cn/ameda/float64s.go | 684 ++++ .../henrylee2cn/ameda/initialize.go | 299 ++ vendor/github.com/henrylee2cn/ameda/int.go | 206 + vendor/github.com/henrylee2cn/ameda/int16.go | 186 + vendor/github.com/henrylee2cn/ameda/int16s.go | 678 ++++ vendor/github.com/henrylee2cn/ameda/int32.go | 192 + vendor/github.com/henrylee2cn/ameda/int32s.go | 682 ++++ vendor/github.com/henrylee2cn/ameda/int64.go | 201 + vendor/github.com/henrylee2cn/ameda/int64s.go | 692 ++++ vendor/github.com/henrylee2cn/ameda/int8.go | 179 + vendor/github.com/henrylee2cn/ameda/int8s.go | 679 ++++ .../github.com/henrylee2cn/ameda/interface.go | 812 ++++ .../henrylee2cn/ameda/interfaces.go | 643 +++ vendor/github.com/henrylee2cn/ameda/ints.go | 682 ++++ vendor/github.com/henrylee2cn/ameda/itoa62.go | 210 + vendor/github.com/henrylee2cn/ameda/itoa_x.go | 21 + vendor/github.com/henrylee2cn/ameda/string.go | 242 ++ .../github.com/henrylee2cn/ameda/strings.go | 710 ++++ .../github.com/henrylee2cn/ameda/typconv.go | 138 + vendor/github.com/henrylee2cn/ameda/uint.go | 203 + vendor/github.com/henrylee2cn/ameda/uint16.go | 174 + .../github.com/henrylee2cn/ameda/uint16s.go | 668 ++++ vendor/github.com/henrylee2cn/ameda/uint32.go | 180 + .../github.com/henrylee2cn/ameda/uint32s.go | 676 ++++ vendor/github.com/henrylee2cn/ameda/uint64.go | 189 + .../github.com/henrylee2cn/ameda/uint64s.go | 688 ++++ vendor/github.com/henrylee2cn/ameda/uint8.go | 168 + vendor/github.com/henrylee2cn/ameda/uint8s.go | 658 ++++ vendor/github.com/henrylee2cn/ameda/uints.go | 686 ++++ vendor/github.com/henrylee2cn/ameda/utils.go | 107 + vendor/github.com/henrylee2cn/ameda/value.go | 301 ++ .../github.com/henrylee2cn/goutil/README.md | 27 - .../github.com/henrylee2cn/goutil/encrypt.go | 91 - vendor/github.com/henrylee2cn/goutil/go.mod | 5 - vendor/github.com/henrylee2cn/goutil/go.sum | 12 - .../github.com/henrylee2cn/goutil/gotest.go | 31 - vendor/github.com/henrylee2cn/goutil/sets.go | 479 --- vendor/golang.org/x/net/html/const.go | 3 +- vendor/golang.org/x/net/html/foreign.go | 120 +- vendor/golang.org/x/net/html/node.go | 5 + vendor/golang.org/x/net/html/parse.go | 337 +- vendor/golang.org/x/net/html/render.go | 34 +- vendor/golang.org/x/net/html/token.go | 3 +- vendor/golang.org/x/text/encoding/encoding.go | 2 +- .../x/text/encoding/htmlindex/tables.go | 1 + .../internal/identifier/identifier.go | 2 +- .../text/encoding/internal/identifier/mib.go | 96 +- .../encoding/simplifiedchinese/hzgb2312.go | 2 +- .../x/text/encoding/unicode/unicode.go | 96 +- .../x/text/{ => internal}/language/common.go | 12 +- .../x/text/internal/language/compact.go | 29 + .../text/internal/language/compact/compact.go | 61 + .../internal/language/compact/language.go | 260 ++ .../text/internal/language/compact/parents.go | 120 + .../text/internal/language/compact/tables.go | 1015 +++++ .../x/text/internal/language/compact/tags.go | 91 + .../x/text/internal/language/compose.go | 167 + .../x/text/internal/language/coverage.go | 28 + .../x/text/internal/language/language.go | 627 +++ .../x/text/{ => internal}/language/lookup.go | 120 +- .../x/text/internal/language/match.go | 226 ++ .../x/text/internal/language/parse.go | 604 +++ .../x/text/internal/language/tables.go | 3464 ++++++++++++++++ .../x/text/internal/language/tags.go | 48 + vendor/golang.org/x/text/language/Makefile | 16 - vendor/golang.org/x/text/language/coverage.go | 34 +- vendor/golang.org/x/text/language/go1_1.go | 1 + vendor/golang.org/x/text/language/go1_2.go | 1 + vendor/golang.org/x/text/language/index.go | 783 ---- vendor/golang.org/x/text/language/language.go | 724 +--- vendor/golang.org/x/text/language/match.go | 422 +- vendor/golang.org/x/text/language/parse.go | 753 +--- vendor/golang.org/x/text/language/tables.go | 3500 +---------------- vendor/golang.org/x/text/language/tags.go | 160 +- .../golang.org/x/text/transform/transform.go | 12 +- vendor/modules.txt | 16 +- 125 files changed, 23718 insertions(+), 6937 deletions(-) rename vendor/github.com/{henrylee2cn => andeya}/goutil/.gitignore (97%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/.travis.yml (72%) create mode 100644 vendor/github.com/andeya/goutil/LICENSE create mode 100644 vendor/github.com/andeya/goutil/README.md rename vendor/github.com/{henrylee2cn => andeya}/goutil/currip.go (88%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/doc.go (100%) create mode 100644 vendor/github.com/andeya/goutil/encrypt.go rename vendor/github.com/{henrylee2cn => andeya}/goutil/file.go (100%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/gopath.go (100%) create mode 100644 vendor/github.com/andeya/goutil/gotest.go rename vendor/github.com/{henrylee2cn => andeya}/goutil/js_url.go (100%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/kvdata.go (100%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/map.go (98%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/other.go (88%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/pid_file.go (100%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/random.go (61%) create mode 100644 vendor/github.com/andeya/goutil/sets.go rename vendor/github.com/{henrylee2cn => andeya}/goutil/string.go (74%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/targz.go (100%) rename vendor/github.com/{henrylee2cn => andeya}/goutil/trace.go (100%) rename vendor/github.com/{henrylee2cn/goutil/exported.go => andeya/goutil/type.go} (55%) create mode 100644 vendor/github.com/henrylee2cn/ameda/.gitignore create mode 100644 vendor/github.com/henrylee2cn/ameda/LICENSE create mode 100644 vendor/github.com/henrylee2cn/ameda/README.md create mode 100644 vendor/github.com/henrylee2cn/ameda/atoi62.go create mode 100644 vendor/github.com/henrylee2cn/ameda/atoi_x.go create mode 100644 vendor/github.com/henrylee2cn/ameda/bool.go create mode 100644 vendor/github.com/henrylee2cn/ameda/bools.go create mode 100644 vendor/github.com/henrylee2cn/ameda/float32.go create mode 100644 vendor/github.com/henrylee2cn/ameda/float32s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/float64.go create mode 100644 vendor/github.com/henrylee2cn/ameda/float64s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/initialize.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int16.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int16s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int32.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int32s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int64.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int64s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int8.go create mode 100644 vendor/github.com/henrylee2cn/ameda/int8s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/interface.go create mode 100644 vendor/github.com/henrylee2cn/ameda/interfaces.go create mode 100644 vendor/github.com/henrylee2cn/ameda/ints.go create mode 100644 vendor/github.com/henrylee2cn/ameda/itoa62.go create mode 100644 vendor/github.com/henrylee2cn/ameda/itoa_x.go create mode 100644 vendor/github.com/henrylee2cn/ameda/string.go create mode 100644 vendor/github.com/henrylee2cn/ameda/strings.go create mode 100644 vendor/github.com/henrylee2cn/ameda/typconv.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint16.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint16s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint32.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint32s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint64.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint64s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint8.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uint8s.go create mode 100644 vendor/github.com/henrylee2cn/ameda/uints.go create mode 100644 vendor/github.com/henrylee2cn/ameda/utils.go create mode 100644 vendor/github.com/henrylee2cn/ameda/value.go delete mode 100644 vendor/github.com/henrylee2cn/goutil/README.md delete mode 100644 vendor/github.com/henrylee2cn/goutil/encrypt.go delete mode 100644 vendor/github.com/henrylee2cn/goutil/go.mod delete mode 100644 vendor/github.com/henrylee2cn/goutil/go.sum delete mode 100644 vendor/github.com/henrylee2cn/goutil/gotest.go delete mode 100644 vendor/github.com/henrylee2cn/goutil/sets.go rename vendor/golang.org/x/text/{ => internal}/language/common.go (50%) create mode 100644 vendor/golang.org/x/text/internal/language/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/compact.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/language.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/parents.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/compact/tags.go create mode 100644 vendor/golang.org/x/text/internal/language/compose.go create mode 100644 vendor/golang.org/x/text/internal/language/coverage.go create mode 100644 vendor/golang.org/x/text/internal/language/language.go rename vendor/golang.org/x/text/{ => internal}/language/lookup.go (80%) create mode 100644 vendor/golang.org/x/text/internal/language/match.go create mode 100644 vendor/golang.org/x/text/internal/language/parse.go create mode 100644 vendor/golang.org/x/text/internal/language/tables.go create mode 100644 vendor/golang.org/x/text/internal/language/tags.go delete mode 100644 vendor/golang.org/x/text/language/Makefile delete mode 100644 vendor/golang.org/x/text/language/index.go diff --git a/LICENSE b/LICENSE index 1362fc0..5c63220 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2015 HenryLee + Copyright 2022 AndeyaLee Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index fc85c78..73f090b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Surfer [![GitHub release](https://img.shields.io/github/release/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/releases) [![report card](https://goreportcard.com/badge/github.com/henrylee2cn/surfer?style=flat-square)](http://goreportcard.com/report/henrylee2cn/surfer) [![github issues](https://img.shields.io/github/issues/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/issues?q=is%3Aopen+is%3Aissue) [![github closed issues](https://img.shields.io/github/issues-closed-raw/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/issues?q=is%3Aissue+is%3Aclosed) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/henrylee2cn/surfer) [![view Go大数据](https://img.shields.io/badge/官方QQ群-Go大数据(42731170)-27a5ea.svg?style=flat-square)](http://jq.qq.com/?_wv=1027&k=XnGGnc) +# Surfer [![GitHub release](https://img.shields.io/github/release/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/releases) [![report card](https://goreportcard.com/badge/github.com/andeya/surfer?style=flat-square)](http://goreportcard.com/report/andeya/surfer) [![github issues](https://img.shields.io/github/issues/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/issues?q=is%3Aopen+is%3Aissue) [![github closed issues](https://img.shields.io/github/issues-closed-raw/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/issues?q=is%3Aissue+is%3Aclosed) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/andeya/surfer) [![view Go大数据](https://img.shields.io/badge/官方QQ群-Go大数据(42731170)-27a5ea.svg?style=flat-square)](http://jq.qq.com/?_wv=1027&k=XnGGnc) Package surfer is a high level concurrency http client. It has `surf` and` phantom` download engines, highly simulated browser behavior, the function of analog login and so on. -[简体中文](https://github.com/henrylee2cn/surfer/blob/master/README_ZH.md) +[简体中文](https://github.com/andeya/surfer/blob/master/README_ZH.md) ## Features - Both `surf` and `phantomjs` engines are supported @@ -16,7 +16,7 @@ It has `surf` and` phantom` download engines, highly simulated browser behavior, package main import ( - "github.com/henrylee2cn/surfer" + "github.com/andeya/surfer" "io/ioutil" "log" ) @@ -24,7 +24,7 @@ import ( func main() { // Use surf engine resp, err := surfer.Download(&surfer.Request{ - Url: "http://github.com/henrylee2cn/surfer", + Url: "http://github.com/andeya/surfer", }) if err != nil { log.Fatal(err) @@ -35,7 +35,7 @@ func main() { // Use phantomjs engine surfer.SetPhantomJsFilePath("Path to phantomjs.exe") resp, err = surfer.Download(&surfer.Request{ - Url: "http://github.com/henrylee2cn", + Url: "http://github.com/andeya", DownloaderID: 1, }) if err != nil { @@ -48,8 +48,8 @@ func main() { surfer.DestroyJsFiles() } ``` -[Full example](https://github.com/henrylee2cn/surfer/tree/master/example) +[Full example](https://github.com/andeya/surfer/tree/master/example) ## License -Surfer is under Apache v2 License. See the [LICENSE](https://github.com/henrylee2cn/surfer/raw/master/LICENSE) file for the full license text. +Surfer is under Apache v2 License. See the [LICENSE](https://github.com/andeya/surfer/raw/master/LICENSE) file for the full license text. diff --git a/README_ZH.md b/README_ZH.md index 7fdf3d7..7bda880 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -1,9 +1,9 @@ -# Surfer [![GitHub release](https://img.shields.io/github/release/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/releases) [![report card](https://goreportcard.com/badge/github.com/henrylee2cn/surfer?style=flat-square)](http://goreportcard.com/report/henrylee2cn/surfer) [![github issues](https://img.shields.io/github/issues/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/issues?q=is%3Aopen+is%3Aissue) [![github closed issues](https://img.shields.io/github/issues-closed-raw/henrylee2cn/surfer.svg?style=flat-square)](https://github.com/henrylee2cn/surfer/issues?q=is%3Aissue+is%3Aclosed) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/henrylee2cn/surfer) [![view Go大数据](https://img.shields.io/badge/官方QQ群-Go大数据(42731170)-27a5ea.svg?style=flat-square)](http://jq.qq.com/?_wv=1027&k=XnGGnc) +# Surfer [![GitHub release](https://img.shields.io/github/release/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/releases) [![report card](https://goreportcard.com/badge/github.com/andeya/surfer?style=flat-square)](http://goreportcard.com/report/andeya/surfer) [![github issues](https://img.shields.io/github/issues/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/issues?q=is%3Aopen+is%3Aissue) [![github closed issues](https://img.shields.io/github/issues-closed-raw/andeya/surfer.svg?style=flat-square)](https://github.com/andeya/surfer/issues?q=is%3Aissue+is%3Aclosed) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/andeya/surfer) [![view Go大数据](https://img.shields.io/badge/官方QQ群-Go大数据(42731170)-27a5ea.svg?style=flat-square)](http://jq.qq.com/?_wv=1027&k=XnGGnc) Surfer 是一款Go语言编写的高并发 web 客户端,拥有surf与phantom两种下载内核,高度模拟浏览器行为,可实现模拟登录等功能。 -高并发爬虫[Pholcus](https://github.com/henrylee2cn/pholcus)的专用下载器。 +高并发爬虫[Pholcus](https://github.com/andeya/pholcus)的专用下载器。 ## 特性 @@ -17,7 +17,7 @@ Surfer 是一款Go语言编写的高并发 web 客户端,拥有surf与phantom package main import ( - "github.com/henrylee2cn/surfer" + "github.com/andeya/surfer" "io/ioutil" "log" ) @@ -25,7 +25,7 @@ import ( func main() { // 默认使用surf内核下载 resp, err := surfer.Download(&surfer.Request{ - Url: "http://github.com/henrylee2cn/surfer", + Url: "http://github.com/andeya/surfer", }) if err != nil { log.Fatal(err) @@ -36,7 +36,7 @@ func main() { // 指定使用phantomjs内核下载 surfer.SetPhantomJsFilePath("Path to phantomjs.exe") resp, err = surfer.Download(&surfer.Request{ - Url: "http://github.com/henrylee2cn", + Url: "http://github.com/andeya", DownloaderID: 1, }) if err != nil { @@ -50,9 +50,9 @@ func main() { } ``` -[完整示例](https://github.com/henrylee2cn/surfer/tree/master/example) +[完整示例](https://github.com/andeya/surfer/tree/master/example) ## 开源协议 -Surfer 项目采用商业应用友好的[Apache License v2](https://github.com/henrylee2cn/surfer/raw/master/LICENSE).发布 +Surfer 项目采用商业应用友好的[Apache License v2](https://github.com/andeya/surfer/raw/master/LICENSE).发布 diff --git a/agent.go b/agent.go index 8a16a36..a4ecfb9 100644 --- a/agent.go +++ b/agent.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/body.go b/body.go index 8ff6da1..43ef067 100644 --- a/body.go +++ b/body.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import ( "mime/multipart" "net/url" - "github.com/henrylee2cn/goutil" + "github.com/andeya/goutil" ) // body set request body diff --git a/example/example001/example.go b/example/example001/example.go index 116d145..6f874a9 100644 --- a/example/example001/example.go +++ b/example/example001/example.go @@ -1,11 +1,12 @@ package example001 import ( - "github.com/henrylee2cn/surfer" "io/ioutil" "log" "net/url" "time" + + "github.com/andeya/surfer" ) func main() { diff --git a/example/example002/example.go b/example/example002/example.go index 2c164bb..00c684b 100644 --- a/example/example002/example.go +++ b/example/example002/example.go @@ -1,11 +1,12 @@ package main import ( - "github.com/henrylee2cn/surfer" "io/ioutil" "log" "net/url" "time" + + "github.com/andeya/surfer" ) const ( @@ -58,7 +59,7 @@ func main() { resp, err = surfer.Download(&surfer.Request{ Url: "http://httpbin.org/get", DownloaderID: 1, - DialTimeout: time.Millisecond * 2000, //设置超时时间 + DialTimeout: time.Millisecond * 2000, // 设置超时时间 }) handleError(err) @@ -71,14 +72,14 @@ func main() { log.Println("resp.Body=", string(b)) // 4.phantomjs内核POST下载测试开始--------------------------------------------------------------------------- - surfer.SetPhantomJsFilePath("../phantomjs.exe") //相对路径 + surfer.SetPhantomJsFilePath("../phantomjs.exe") // 相对路径 log.Println("phantomjs内核POST下载测试开始" + HR) resp, err = surfer.Download(&surfer.Request{ DownloaderID: 1, Url: "http://httpbin.org/post", Method: "POST", Body: form, - DialTimeout: time.Millisecond * 2000, //设置超时时间 + DialTimeout: time.Millisecond * 2000, // 设置超时时间 }) handleError(err) log.Println("resp.Status=", resp.Status) diff --git a/example/example003/example.go b/example/example003/example.go index d9e3afc..5cf4fea 100644 --- a/example/example003/example.go +++ b/example/example003/example.go @@ -1,9 +1,10 @@ package main import ( - "github.com/henrylee2cn/surfer" "log" "time" + + "github.com/andeya/surfer" ) const ( @@ -11,7 +12,7 @@ const ( ) func main() { - //默认内核 + // 默认内核 log.Println("默认内核timeout" + HR) log.Println(time.Now(), "start") resp, err := surfer.Download(&surfer.Request{ @@ -26,7 +27,7 @@ func main() { log.Println("resp.Status=", resp.Status) } - //phantomjs内核 + // phantomjs内核 surfer.SetPhantomJsFilePath("E:/Workspace/go-labs/src/lab089/lab003/phantomjs/phantomjs.exe") log.Println("phantomjs内核" + HR) log.Println(time.Now(), "start") diff --git a/example/example004/example.go b/example/example004/example.go index 49f3129..5eb1104 100644 --- a/example/example004/example.go +++ b/example/example004/example.go @@ -1,12 +1,13 @@ package main import ( - "github.com/henrylee2cn/surfer" "io/ioutil" "log" "net/http" "net/http/cookiejar" "net/url" + + "github.com/andeya/surfer" ) const ( @@ -14,7 +15,7 @@ const ( ) func main() { - //默认内核 + // 默认内核 jar1, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ @@ -28,7 +29,7 @@ func main() { u, _ := url.Parse("http://httpbin.org/cookies") jar1.SetCookies(u, cookies) - //查看cookie------------------------------------------------------------------------------------- + // 查看cookie------------------------------------------------------------------------------------- log.Println("查看Cookie" + HR) defaultSurfer := surfer.New(jar1) resp, err := defaultSurfer.Download(&surfer.Request{ @@ -43,7 +44,7 @@ func main() { log.Println("body=", string(b)) log.Println("cookie=", jar1.Cookies(u)) - //设置cookie------------------------------------------------------------------------------------- + // 设置cookie------------------------------------------------------------------------------------- log.Println("设置Cookie" + HR) resp, err = defaultSurfer.Download(&surfer.Request{ Url: "http://httpbin.org/cookies/set?k2=v2&k1=v1", diff --git a/example/example005/example.go b/example/example005/example.go index b596c4d..1d43e87 100644 --- a/example/example005/example.go +++ b/example/example005/example.go @@ -1,13 +1,14 @@ package main import ( - "github.com/henrylee2cn/surfer" "io/ioutil" "log" "net/http" "net/http/cookiejar" "net/url" "time" + + "github.com/andeya/surfer" ) const ( @@ -15,7 +16,7 @@ const ( ) func main() { - //phantomjs内核 + // phantomjs内核 jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ @@ -29,7 +30,7 @@ func main() { u, _ := url.Parse("http://httpbin.org/cookies") jar.SetCookies(u, cookies) - //查看cookie------------------------------------------------------------------ + // 查看cookie------------------------------------------------------------------ log.Println("查看cookie" + HR) phantomSurfer := surfer.NewPhantom("E:\\Workspace\\go-labs\\src\\lab089\\phantomjs.exe", "./tmp", jar) resp, err := phantomSurfer.Download(&surfer.Request{ @@ -47,7 +48,7 @@ func main() { resp.Body.Close() log.Println("resp.Body=", string(b)) - //设置cookie------------------------------------------------------------------ + // 设置cookie------------------------------------------------------------------ log.Println("设置cookie" + HR) resp, err = phantomSurfer.Download(&surfer.Request{ Url: "http://httpbin.org/cookies/set?k2=v2&k1=v1", @@ -64,7 +65,7 @@ func main() { resp.Body.Close() log.Println("resp.Body=", string(b)) - //删除js文件 + // 删除js文件 phantomSurfer.(*surfer.Phantom).DestroyJsFiles() time.Sleep(10e9) } diff --git a/go.mod b/go.mod index 3933986..7068416 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,13 @@ -// Deprecated: Use the "github.com/andeya/surfer" module instead. -module github.com/henrylee2cn/surfer +module github.com/andeya/surfer require ( - github.com/henrylee2cn/goutil v0.0.0-20190925102525-a28b3dc837cc - golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 + github.com/andeya/goutil v0.0.0-20220626152529-9b7868da7b6d + golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e ) -go 1.13 +require ( + github.com/henrylee2cn/ameda v1.4.10 // indirect + golang.org/x/text v0.3.7 // indirect +) + +go 1.18 diff --git a/go.sum b/go.sum index c53a32e..524b3fc 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,18 @@ +github.com/andeya/goutil v0.0.0-20220626152529-9b7868da7b6d h1:SFmlknB2bt6VEND93Uu55IP1HK5CXEk0sTUtxdr+CJQ= +github.com/andeya/goutil v0.0.0-20220626152529-9b7868da7b6d/go.mod h1:29HngAq7SN4CEJuycvNReDnCGYgCUzB9JzrFTj/u0xg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/henrylee2cn/goutil v0.0.0-20190807075143-e8afa09140e9 h1:a2H8nokxD0y7RtMAD0c0iyRjIc6PPBopF2/8zw5kFiE= -github.com/henrylee2cn/goutil v0.0.0-20190807075143-e8afa09140e9/go.mod h1:I9qYeMYwdKC7UFXMECNzCEv0fYuolqLeBMqsmeG7IVo= -github.com/henrylee2cn/goutil v0.0.0-20190925102525-a28b3dc837cc h1:b4gkMTuTTNcGe4mXaNkqtO+pxua81JedxBy2xmAJy4M= -github.com/henrylee2cn/goutil v0.0.0-20190925102525-a28b3dc837cc/go.mod h1:81hpTd0/0IQ9/yK+HKFg489/HHZWEpslCQtbV8M0P3U= +github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQyCAk= +github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA= -golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/phantom.go b/phantom.go index 3f4d1b0..cf9b209 100644 --- a/phantom.go +++ b/phantom.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,9 +34,9 @@ type ( // 效率较surfer会慢很多,但是因为模拟浏览器,破防性更好 // 支持UserAgent/TryTimes/RetryPause/自定义js Phantom struct { - PhantomjsFile string //Phantomjs完整文件名 - TempJsDir string //临时js存放目录 - jsFileMap map[string]string //已存在的js文件 + PhantomjsFile string // Phantomjs完整文件名 + TempJsDir string // 临时js存放目录 + jsFileMap map[string]string // 已存在的js文件 CookieJar *cookiejar.Jar } // Response 用于解析Phantomjs的响应内容 @@ -50,7 +50,7 @@ type ( } } - //给phantomjs传输cookie用 + // 给phantomjs传输cookie用 Cookie struct { Name string `json:"name"` Value string `json:"value"` @@ -169,12 +169,12 @@ func (phantom *Phantom) Download(req *Request) (resp *http.Response, err error) continue } - //设置header + // 设置header for _, h := range retResp.Header { resp.Header.Add(h.Name, h.Value) } - //设置cookie + // 设置cookie for _, c := range retResp.Cookies { resp.Header.Add("Set-Cookie", c) } diff --git a/request.go b/request.go index 661ae0f..16e42b6 100644 --- a/request.go +++ b/request.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/surf.go b/surf.go index ca8689b..74e1a5e 100644 --- a/surf.go +++ b/surf.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import ( "strings" "time" - "github.com/henrylee2cn/goutil" + "github.com/andeya/goutil" ) // Surf is the default Download implementation. diff --git a/surfer.go b/surfer.go index 1c2b513..de12086 100644 --- a/surfer.go +++ b/surfer.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ // package main // // import ( -// "github.com/henrylee2cn/surfer" +// "github.com/andeya/surfer" // "io/ioutil" // "log" // ) @@ -34,7 +34,7 @@ // func main() { // // Use surf engine // resp, err := surfer.Download(&surfer.Request{ -// Url: "http://github.com/henrylee2cn/surfer", +// Url: "http://github.com/andeya/surfer", // }) // if err != nil { // log.Fatal(err) @@ -44,7 +44,7 @@ // // // Use phantomjs engine // resp, err = surfer.Download(&surfer.Request{ -// Url: "http://github.com/henrylee2cn", +// Url: "http://github.com/andeya", // DownloaderID: 1, // }) // if err != nil { diff --git a/surfer_test.go b/surfer_test.go index c4ae242..9b99394 100644 --- a/surfer_test.go +++ b/surfer_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/util.go b/util.go index 4934b1e..74d9096 100644 --- a/util.go +++ b/util.go @@ -1,4 +1,4 @@ -// Copyright 2015 henrylee2cn Author. All Rights Reserved. +// Copyright 2015 andeya Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/vendor/github.com/henrylee2cn/goutil/.gitignore b/vendor/github.com/andeya/goutil/.gitignore similarity index 97% rename from vendor/github.com/henrylee2cn/goutil/.gitignore rename to vendor/github.com/andeya/goutil/.gitignore index 87b70ba..6740a7e 100644 --- a/vendor/github.com/henrylee2cn/goutil/.gitignore +++ b/vendor/github.com/andeya/goutil/.gitignore @@ -37,3 +37,6 @@ _testmain.go *.sublime-project *.sublime-workspace .DS_Store +.idea +.vscode + diff --git a/vendor/github.com/henrylee2cn/goutil/.travis.yml b/vendor/github.com/andeya/goutil/.travis.yml similarity index 72% rename from vendor/github.com/henrylee2cn/goutil/.travis.yml rename to vendor/github.com/andeya/goutil/.travis.yml index 6ffb00c..883bebb 100644 --- a/vendor/github.com/henrylee2cn/goutil/.travis.yml +++ b/vendor/github.com/andeya/goutil/.travis.yml @@ -8,7 +8,7 @@ go: - "1.11" - "1.12" - "1.13" -go_import_path: github.com/henrylee2cn/goutil +go_import_path: github.com/andeya/goutil env: - GIMME_ARCH=amd64 GO111MODULE=on - GIMME_ARCH=386 GO111MODULE=on diff --git a/vendor/github.com/andeya/goutil/LICENSE b/vendor/github.com/andeya/goutil/LICENSE new file mode 100644 index 0000000..dd72658 --- /dev/null +++ b/vendor/github.com/andeya/goutil/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2022 AndeyaLee + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/andeya/goutil/README.md b/vendor/github.com/andeya/goutil/README.md new file mode 100644 index 0000000..590943c --- /dev/null +++ b/vendor/github.com/andeya/goutil/README.md @@ -0,0 +1,9 @@ +# goutil [![Build Status](https://travis-ci.org/andeya/goutil.svg?branch=mgoutil)](https://travis-ci.org/andeya/goutil) [![report card](https://goreportcard.com/badge/github.com/andeya/goutil?style=flat-square)](http://goreportcard.com/report/andeya/goutil) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/andeya/goutil) + +Golang common tool functions or components. + +## Inclusion criteria + +- Only rely on the Go standard package +- Functions or lightweight packages +- Non-business related general tools diff --git a/vendor/github.com/henrylee2cn/goutil/currip.go b/vendor/github.com/andeya/goutil/currip.go similarity index 88% rename from vendor/github.com/henrylee2cn/goutil/currip.go rename to vendor/github.com/andeya/goutil/currip.go index 5bfdea8..b67d263 100644 --- a/vendor/github.com/henrylee2cn/goutil/currip.go +++ b/vendor/github.com/andeya/goutil/currip.go @@ -14,9 +14,9 @@ import ( func ExtranetIP() (ip string, err error) { defer func() { if p := recover(); p != nil { - err = fmt.Errorf("Get external IP error: %v", p) + err = fmt.Errorf("get external IP error: %v", p) } else if err != nil { - err = errors.New("Get external IP error: " + err.Error()) + err = errors.New("get external IP error: " + err.Error()) } }() resp, err := http.Get("http://pv.sohu.com/cityjson?ie=utf-8") @@ -71,5 +71,5 @@ func IntranetIP() (string, error) { return ip.String(), nil } } - return "", errors.New("Are you connected to the network?") + return "", errors.New("no network connection") } diff --git a/vendor/github.com/henrylee2cn/goutil/doc.go b/vendor/github.com/andeya/goutil/doc.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/doc.go rename to vendor/github.com/andeya/goutil/doc.go diff --git a/vendor/github.com/andeya/goutil/encrypt.go b/vendor/github.com/andeya/goutil/encrypt.go new file mode 100644 index 0000000..e6014e5 --- /dev/null +++ b/vendor/github.com/andeya/goutil/encrypt.go @@ -0,0 +1,274 @@ +package goutil + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/md5" + "crypto/rand" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/base64" + "encoding/hex" + "errors" + "hash/fnv" + "io" + + "github.com/henrylee2cn/ameda" +) + +// Md5 returns the MD5 checksum string of the data. +func Md5(b []byte) string { + checksum := md5.Sum(b) + return hex.EncodeToString(checksum[:]) +} + +// Sha1 returns the sha1 checksum string of the data. +func Sha1(b []byte) string { + checksum := sha1.Sum(b) + return hex.EncodeToString(checksum[:]) +} + +// Sha256 returns the sha256 checksum string of the data. +func Sha256(b []byte) string { + checksum := sha256.Sum256(b) + return hex.EncodeToString(checksum[:]) +} + +// Sha512 returns the sha512 checksum string of the data. +func Sha512(b []byte) string { + checksum := sha512.Sum512(b) + return hex.EncodeToString(checksum[:]) +} + +// Fnv1aToUint64 returns the 64-bit FNV-1a hash sum of b. +func Fnv1aToUint64(b []byte) uint64 { + h := fnv.New64a() + h.Reset() + h.Write(b) + return h.Sum64() +} + +// Fnv1aToUint32 returns the 32-bit FNV-1a hash sum of b. +func Fnv1aToUint32(b []byte) uint32 { + h := fnv.New32a() + h.Reset() + h.Write(b) + return h.Sum32() +} + +// AESEncrypt uses ECB mode to encrypt a piece of data and then encodes it in hex. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESEncrypt(cipherkey, plaintext []byte, useBase64 ...bool) []byte { + block := mustNewCipher(cipherkey) + blockSize := block.BlockSize() + plaintext = pkcs5Padding(plaintext, blockSize) + r := make([]byte, len(plaintext)) + dst := r + for len(plaintext) > 0 { + block.Encrypt(dst, plaintext) + plaintext = plaintext[blockSize:] + dst = dst[blockSize:] + } + return encode(r, useBase64) +} + +// AESDecrypt hex decodes a piece of data and then decrypts it using ECB mode. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESDecrypt(cipherkey, ciphertext []byte, useBase64 ...bool) ([]byte, error) { + src, err := decode(ciphertext, useBase64) + if err != nil { + return nil, err + } + block, err := aes.NewCipher(cipherkey) + if err != nil { + return nil, err + } + blockSize := block.BlockSize() + r := make([]byte, len(src)) + dst := r + for len(src) > 0 { + block.Decrypt(dst, src) + src = src[blockSize:] + dst = dst[blockSize:] + } + return pkcs5Unpadding(r) +} + +// AESCBCEncrypt uses CBC mode to encrypt a piece of data and then encodes it in hex. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESCBCEncrypt(cipherkey, plaintext []byte, useBase64 ...bool) []byte { + block := mustNewCipher(cipherkey) + blockSize := block.BlockSize() + plaintext = pkcs5Padding(plaintext, blockSize) + // The IV needs to be unique, but not secure. Therefore it's common to + // include it at the beginning of the ciphertext. + ciphertext := make([]byte, aes.BlockSize+len(plaintext)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic(err) + } + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) + return encode(ciphertext, useBase64) +} + +// AESCBCDecrypt hex decodes a piece of data and then decrypts it using CBC mode. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESCBCDecrypt(cipherkey, ciphertext []byte, useBase64 ...bool) ([]byte, error) { + ciphertext, err := decode(ciphertext, useBase64) + if err != nil { + return nil, err + } + // The IV needs to be unique, but not secure. Therefore it's common to + // include it at the beginning of the ciphertext. + if len(ciphertext) < aes.BlockSize { + return nil, errors.New("ciphertext too short") + } + iv := ciphertext[:aes.BlockSize] + ciphertext = ciphertext[aes.BlockSize:] + // CBC mode always works in whole blocks. + if len(ciphertext)%aes.BlockSize != 0 { + return nil, errors.New("ciphertext is not a multiple of the block size") + } + block, err := aes.NewCipher(cipherkey) + if err != nil { + return nil, err + } + mode := cipher.NewCBCDecrypter(block, iv) + // CryptBlocks can work in-place if the two arguments are the same. + plaintext := ciphertext + mode.CryptBlocks(plaintext, ciphertext) + return pkcs5Unpadding(plaintext) +} + +// AESCTREncrypt uses CTR mode to encrypt a piece of data and then encodes it in hex. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESCTREncrypt(cipherkey, plaintext []byte, useBase64 ...bool) []byte { + block := mustNewCipher(cipherkey) + // The IV needs to be unique, but not secure. Therefore it's common to + // include it at the beginning of the ciphertext. + ciphertext := make([]byte, aes.BlockSize+len(plaintext)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic(err) + } + stream := cipher.NewCTR(block, iv) + stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) + return encode(ciphertext, useBase64) +} + +// AESCTRDecrypt hex decodes a piece of data and then decrypts it using CTR mode. +// The cipherkey argument should be the AES key, +// either 16, 24, or 32 bytes to select +// AES-128, AES-192, or AES-256. +func AESCTRDecrypt(cipherkey, ciphertext []byte, useBase64 ...bool) ([]byte, error) { + ciphertext, err := decode(ciphertext, useBase64) + if err != nil { + return nil, err + } + // The IV needs to be unique, but not secure. Therefore it's common to + // include it at the beginning of the ciphertext. + if len(ciphertext) < aes.BlockSize { + return nil, errors.New("ciphertext too short") + } + iv := ciphertext[:aes.BlockSize] + ciphertext = ciphertext[aes.BlockSize:] + block, err := aes.NewCipher(cipherkey) + if err != nil { + return nil, err + } + stream := cipher.NewCTR(block, iv) + plaintext := ciphertext + // XORKeyStream can work in-place if the two arguments are the same. + stream.XORKeyStream(plaintext, ciphertext) + return plaintext, nil +} + +func mustNewCipher(cipherkey []byte) cipher.Block { + block, err := aes.NewCipher(cipherkey) + if err != nil { + panic(err) + } + return block +} + +func pkcs5Padding(plaintext []byte, blockSize int) []byte { + n := byte(blockSize - len(plaintext)%blockSize) + for i := byte(0); i < n; i++ { + plaintext = append(plaintext, n) + } + return plaintext +} + +func pkcs5Unpadding(r []byte) ([]byte, error) { + l := len(r) + if l == 0 { + return nil, errors.New("input padded bytes is empty") + } + last := int(r[l-1]) + if l-last < 0 { + return nil, errors.New("input padded bytes is invalid") + } + n := byte(last) + pad := r[l-last : l] + isPad := true + for _, v := range pad { + if v != n { + isPad = false + break + } + } + if !isPad { + return nil, errors.New("remove pad error") + } + return r[:l-last], nil +} + +func encode(src []byte, useBase64 []bool) []byte { + if ameda.OneBool(useBase64) { + return base64Encode(src) + } + return hexEncode(src) +} + +func decode(src []byte, useBase64 []bool) ([]byte, error) { + if ameda.OneBool(useBase64) { + return base64Decode(src) + } + return hexDecode(src) +} + +func hexEncode(src []byte) []byte { + dst := make([]byte, hex.EncodedLen(len(src))) + hex.Encode(dst, src) + return dst +} + +func hexDecode(src []byte) ([]byte, error) { + dst := make([]byte, hex.DecodedLen(len(src))) + _, err := hex.Decode(dst, src) + return dst, err +} + +func base64Encode(src []byte) []byte { + buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(src))) + base64.RawURLEncoding.Encode(buf, src) + return buf +} + +func base64Decode(src []byte) ([]byte, error) { + dst := make([]byte, base64.RawURLEncoding.DecodedLen(len(src))) + n, err := base64.RawURLEncoding.Decode(dst, src) + return dst[:n], err +} diff --git a/vendor/github.com/henrylee2cn/goutil/file.go b/vendor/github.com/andeya/goutil/file.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/file.go rename to vendor/github.com/andeya/goutil/file.go diff --git a/vendor/github.com/henrylee2cn/goutil/gopath.go b/vendor/github.com/andeya/goutil/gopath.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/gopath.go rename to vendor/github.com/andeya/goutil/gopath.go diff --git a/vendor/github.com/andeya/goutil/gotest.go b/vendor/github.com/andeya/goutil/gotest.go new file mode 100644 index 0000000..f2ec806 --- /dev/null +++ b/vendor/github.com/andeya/goutil/gotest.go @@ -0,0 +1,41 @@ +package goutil + +import ( + "os" + "strings" +) + +// IsGoTest returns whether the current process is a test. +func IsGoTest() bool { + return isGoTest +} + +var isGoTest bool + +func init() { + isGoTest = checkGoTestEnv() +} + +const IS_GO_TEST = "IS_GO_TEST" + +func checkGoTestEnv() bool { + for _, arg := range os.Args[1:] { + for _, s := range []string{ + "-test.timeout=", + "-test.timeout", + "-test.run=", + "-test.run", + "-test.bench=", + "-test.bench", + "-test.v=", + "-test.v", + } { + if strings.HasPrefix(arg, s) || arg == s { + return true + } + } + } + env := os.Getenv(IS_GO_TEST) + return env == "1" || env == "true" + // return strings.HasSuffix(os.Args[0], ".test") +} diff --git a/vendor/github.com/henrylee2cn/goutil/js_url.go b/vendor/github.com/andeya/goutil/js_url.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/js_url.go rename to vendor/github.com/andeya/goutil/js_url.go diff --git a/vendor/github.com/henrylee2cn/goutil/kvdata.go b/vendor/github.com/andeya/goutil/kvdata.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/kvdata.go rename to vendor/github.com/andeya/goutil/kvdata.go diff --git a/vendor/github.com/henrylee2cn/goutil/map.go b/vendor/github.com/andeya/goutil/map.go similarity index 98% rename from vendor/github.com/henrylee2cn/goutil/map.go rename to vendor/github.com/andeya/goutil/map.go index fc20f19..beb71c9 100644 --- a/vendor/github.com/henrylee2cn/goutil/map.go +++ b/vendor/github.com/andeya/goutil/map.go @@ -204,7 +204,7 @@ type atomicMap struct { // state) and the next store to the map will make a new dirty copy. misses int - // @added by henrylee2cn 2017/11/17 + // @added by andeya 2017/11/17 length int32 } @@ -289,7 +289,7 @@ func (m *atomicMap) Store(key, value interface{}) { case 1: return case 2: - // @added by henrylee2cn 2017/11/17 + // @added by andeya 2017/11/17 atomic.AddInt32(&m.length, 1) return } @@ -303,7 +303,7 @@ func (m *atomicMap) Store(key, value interface{}) { m.mu.Unlock() return case 2: - // @added by henrylee2cn 2017/11/17 + // @added by andeya 2017/11/17 atomic.AddInt32(&m.length, 1) m.mu.Unlock() return @@ -312,7 +312,7 @@ func (m *atomicMap) Store(key, value interface{}) { // The entry was previously expunged, which implies that there is a // non-nil dirty map and this entry is not in it. m.dirty[key] = e - // @added by henrylee2cn 2017/11/17 + // @added by andeya 2017/11/17 atomic.AddInt32(&m.length, 1) } e.storeLocked(&value) @@ -380,7 +380,7 @@ func (m *atomicMap) LoadOrStore(key, value interface{}) (actual interface{}, loa if e, ok := read.m[key]; ok { actual, loaded, ok := e.tryLoadOrStore(value) if ok { - // @added by henrylee2cn 2017/11/17 + // @added by andeya 2017/11/17 if !loaded { atomic.AddInt32(&m.length, 1) } @@ -395,7 +395,7 @@ func (m *atomicMap) LoadOrStore(key, value interface{}) (actual interface{}, loa m.dirty[key] = e } actual, loaded, ok = e.tryLoadOrStore(value) - // @added by henrylee2cn 2017/12/01 + // @added by andeya 2017/12/01 if ok && !loaded { atomic.AddInt32(&m.length, 1) } @@ -600,14 +600,14 @@ func (e *entry) tryExpungeLocked() (isExpunged bool) { // Len returns the length of the map. // Note: // the length may be inaccurate. -// @added by henrylee2cn 2017/11/17 +// @added by andeya 2017/11/17 func (m *atomicMap) Len() int { return int(atomic.LoadInt32(&m.length)) } // Random returns a pair kv randomly. // If exist=false, no kv data is exist. -// @added by henrylee2cn 2017/08/10 +// @added by andeya 2017/08/10 func (m *atomicMap) Random() (key, value interface{}, exist bool) { var ( length, i int diff --git a/vendor/github.com/henrylee2cn/goutil/other.go b/vendor/github.com/andeya/goutil/other.go similarity index 88% rename from vendor/github.com/henrylee2cn/goutil/other.go rename to vendor/github.com/andeya/goutil/other.go index 41aa9d3..69cc626 100644 --- a/vendor/github.com/henrylee2cn/goutil/other.go +++ b/vendor/github.com/andeya/goutil/other.go @@ -3,6 +3,8 @@ package goutil import ( "reflect" "unsafe" + + "github.com/henrylee2cn/ameda" ) // AddrInt returns a pointer int representing the address of i. @@ -22,6 +24,11 @@ func InitAndGetString(strPtr *string, def string) string { return *strPtr } +// InitPointer initializes null pointer. +func InitPointer(v reflect.Value) bool { + return ameda.InitPointer(v) +} + // DereferenceType dereference, get the underlying non-pointer type. func DereferenceType(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { @@ -119,3 +126,10 @@ func IsLittleEndian() bool { b := *pb return (b == 0x04) } + +const ( + // Is64BitPlatform Whether the current system is a 64-bit platform + Is64BitPlatform bool = (32 << (^uint(0) >> 63)) == 64 + // Is32BitPlatform Whether the current system is a 32-bit platform + Is32BitPlatform bool = (32 << (^uint(0) >> 63)) == 0 +) diff --git a/vendor/github.com/henrylee2cn/goutil/pid_file.go b/vendor/github.com/andeya/goutil/pid_file.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/pid_file.go rename to vendor/github.com/andeya/goutil/pid_file.go diff --git a/vendor/github.com/henrylee2cn/goutil/random.go b/vendor/github.com/andeya/goutil/random.go similarity index 61% rename from vendor/github.com/henrylee2cn/goutil/random.go rename to vendor/github.com/andeya/goutil/random.go index 08a5019..0d12afe 100644 --- a/vendor/github.com/henrylee2cn/goutil/random.go +++ b/vendor/github.com/andeya/goutil/random.go @@ -4,7 +4,10 @@ import ( "bytes" "crypto/rand" "encoding/base64" + "errors" mrand "math/rand" + + "github.com/henrylee2cn/ameda" ) // NewRandom creates a new padded Encoding defined by the given alphabet string. @@ -26,7 +29,7 @@ func NewRandom(alphabet string) *Random { return r } -// Random random string creater. +// Random random string creator. type Random struct { encoding *base64.Encoding substitute []byte @@ -37,16 +40,39 @@ type Random struct { // random string. It will panic if the system's secure random number generator // fails to function correctly. // The length n must be an integer multiple of 4, otherwise the last character will be padded with `=`. -func (r *Random) RandomString(n int) string { - d := r.encoding.DecodedLen(n) - buf := make([]byte, n) +func (r *Random) RandomString(length int) string { + d := r.encoding.DecodedLen(length) + buf := make([]byte, length) r.encoding.Encode(buf, RandomBytes(d)) for k, v := range buf { if v == 0x00 { buf[k] = r.substitute[mrand.Intn(r.substituteLen)] } } - return BytesToString(buf) + return ameda.UnsafeBytesToString(buf) +} + +const tsLen = 6 // base62=ZZZZZZ, unix=56800235583, time=3769-12-05 11:13:03 +0800 CST + +// RandomStringWithTime returns a random string with UNIX timestamp(in second). +// unixTs: range [0,56800235583], that is 56800235583 3769-12-05 11:13:03 +0800 CST to 3769-12-05 11:13:03 +0800 CST +func (r *Random) RandomStringWithTime(length int, unixTs int64) (string, error) { + if length <= tsLen { + return "", errors.New("length is less than 7") + } + if unixTs < 0 || unixTs > 56800235583 { + return "", errors.New("unixTs is out of range [0,56800235583]") + } + return r.RandomString(length-tsLen) + ameda.FormatInt(unixTs, 62), nil +} + +// ParseTime parses UNIX timestamp(in second) from stringWithTime. +func (r *Random) ParseTime(stringWithTime string) (unixTs int64, err error) { + length := len(stringWithTime) + if length <= tsLen { + return 0, errors.New("stringWithTime length is less than 7") + } + return ameda.ParseInt(stringWithTime[length-6:], 62, 64) } const urlEncoder = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" @@ -57,6 +83,11 @@ var urlRandom = &Random{ substituteLen: len(urlEncoder), } +// URLRandom returns Random object with URL encoder. +func URLRandom() *Random { + return urlRandom +} + // URLRandomString returns a URL-safe, base64 encoded securely generated // random string. It will panic if the system's secure random number generator // fails to function correctly. diff --git a/vendor/github.com/andeya/goutil/sets.go b/vendor/github.com/andeya/goutil/sets.go new file mode 100644 index 0000000..b2ecc49 --- /dev/null +++ b/vendor/github.com/andeya/goutil/sets.go @@ -0,0 +1,233 @@ +package goutil + +import ( + "github.com/henrylee2cn/ameda" +) + +// CopyStrings creates a copy of the string slice. +func CopyStrings(a []string) []string { + return ameda.StringsCopy(a) +} + +// StringsToBools converts string slice to bool slice. +func StringsToBools(a []string, emptyAsZero ...bool) ([]bool, error) { + return ameda.StringsToBools(a, emptyAsZero...) +} + +// StringsToFloat32s converts string slice to float32 slice. +func StringsToFloat32s(a []string, emptyAsZero ...bool) ([]float32, error) { + return ameda.StringsToFloat32s(a, emptyAsZero...) +} + +// StringsToFloat64s converts string slice to float64 slice. +func StringsToFloat64s(a []string, emptyAsZero ...bool) ([]float64, error) { + return ameda.StringsToFloat64s(a, emptyAsZero...) +} + +// StringsToInts converts string slice to int slice. +func StringsToInts(a []string, emptyAsZero ...bool) ([]int, error) { + return ameda.StringsToInts(a, emptyAsZero...) +} + +// StringsToInt64s converts string slice to int64 slice. +func StringsToInt64s(a []string, emptyAsZero ...bool) ([]int64, error) { + return ameda.StringsToInt64s(a, emptyAsZero...) +} + +// StringsToInt32s converts string slice to int32 slice. +func StringsToInt32s(a []string, emptyAsZero ...bool) ([]int32, error) { + return ameda.StringsToInt32s(a, emptyAsZero...) +} + +// StringsToInt16s converts string slice to int16 slice. +func StringsToInt16s(a []string, emptyAsZero ...bool) ([]int16, error) { + return ameda.StringsToInt16s(a, emptyAsZero...) +} + +// StringsToInt8s converts string slice to int8 slice. +func StringsToInt8s(a []string, emptyAsZero ...bool) ([]int8, error) { + return ameda.StringsToInt8s(a, emptyAsZero...) +} + +// StringsToUint8s converts string slice to uint8 slice. +func StringsToUint8s(a []string, emptyAsZero ...bool) ([]uint8, error) { + return ameda.StringsToUint8s(a, emptyAsZero...) +} + +// StringsToUint16s converts string slice to uint16 slice. +func StringsToUint16s(a []string, emptyAsZero ...bool) ([]uint16, error) { + return ameda.StringsToUint16s(a, emptyAsZero...) +} + +// StringsToUint32s converts string slice to uint32 slice. +func StringsToUint32s(a []string, emptyAsZero ...bool) ([]uint32, error) { + return ameda.StringsToUint32s(a, emptyAsZero...) +} + +// StringsToUint64s converts string slice to uint64 slice. +func StringsToUint64s(a []string, emptyAsZero ...bool) ([]uint64, error) { + return ameda.StringsToUint64s(a, emptyAsZero...) +} + +// StringsToUints converts string slice to uint slice. +func StringsToUints(a []string, emptyAsZero ...bool) ([]uint, error) { + return ameda.StringsToUints(a, emptyAsZero...) +} + +// StringsConvert converts the string slice to a new slice using fn. +// If fn returns error, exit the conversion and return the error. +func StringsConvert(a []string, fn func(string) (string, error)) ([]string, error) { + ret := make([]string, len(a)) + for i, s := range a { + r, err := fn(s) + if err != nil { + return nil, err + } + ret[i] = r + } + return ret, nil +} + +// StringsConvertMap converts the string slice to a new map using fn. +// If fn returns error, exit the conversion and return the error. +func StringsConvertMap(a []string, fn func(string) (string, error)) (map[string]string, error) { + ret := make(map[string]string, len(a)) + for _, s := range a { + r, err := fn(s) + if err != nil { + return nil, err + } + ret[s] = r + } + return ret, nil +} + +// IntersectStrings calculate intersection of two sets. +func IntersectStrings(set1, set2 []string) []string { + return ameda.StringSetIntersect(set1, set2) +} + +// StringsDistinct creates a string set that +// removes the same elements and returns them in their original order. +func StringsDistinct(a []string) (set []string) { + set = ameda.StringsCopy(a) + ameda.StringsDistinct(&set, true) + return set +} + +// SetToStrings sets a element to the string set. +func SetToStrings(set []string, a ...string) []string { + return ameda.StringsPushDistinct(set, a...) +} + +// RemoveFromStrings removes the first element from the string set. +func RemoveFromStrings(set []string, a string) []string { + ameda.StringsRemoveFirst(&set, a) + return set +} + +// RemoveAllFromStrings removes all the a element from the string set. +func RemoveAllFromStrings(set []string, a string) []string { + ameda.StringsRemoveEvery(&set, a) + return set +} + +// IntsDistinct creates a int set that +// removes the same elements and returns them in their original order. +func IntsDistinct(a []int) (set []int) { + set = ameda.IntsCopy(a) + ameda.IntsDistinct(&set, true) + return set +} + +// SetToInts sets a element to the int set. +func SetToInts(set []int, a int) []int { + return ameda.IntsPushDistinct(set, a) +} + +// RemoveFromInts removes the first element from the int set. +func RemoveFromInts(set []int, a int) []int { + ameda.IntsRemoveFirst(&set, a) + return set +} + +// RemoveAllFromInts removes all the a element from the int set. +func RemoveAllFromInts(set []int, a int) []int { + ameda.IntsRemoveEvery(&set, a) + return set +} + +// Int32sDistinct creates a int32 set that +// removes the same element32s and returns them in their original order. +func Int32sDistinct(a []int32) (set []int32) { + set = ameda.Int32sCopy(a) + ameda.Int32sDistinct(&set, true) + return set +} + +// SetToInt32s sets a element to the int32 set. +func SetToInt32s(set []int32, a int32) []int32 { + return ameda.Int32sPushDistinct(set, a) +} + +// RemoveFromInt32s removes the first element from the int32 set. +func RemoveFromInt32s(set []int32, a int32) []int32 { + ameda.Int32sRemoveFirst(&set, a) + return set +} + +// RemoveAllFromInt32s removes all the a element from the int32 set. +func RemoveAllFromInt32s(set []int32, a int32) []int32 { + ameda.Int32sRemoveEvery(&set, a) + return set +} + +// Int64sDistinct creates a int64 set that +// removes the same element64s and returns them in their original order. +func Int64sDistinct(a []int64) (set []int64) { + set = ameda.Int64sCopy(a) + ameda.Int64sDistinct(&set, true) + return set +} + +// SetToInt64s sets a element to the int64 set. +func SetToInt64s(set []int64, a int64) []int64 { + return ameda.Int64sPushDistinct(set, a) +} + +// RemoveFromInt64s removes the first element from the int64 set. +func RemoveFromInt64s(set []int64, a int64) []int64 { + ameda.Int64sRemoveFirst(&set, a) + return set +} + +// RemoveAllFromInt64s removes all the a element from the int64 set. +func RemoveAllFromInt64s(set []int64, a int64) []int64 { + ameda.Int64sRemoveEvery(&set, a) + return set +} + +// InterfacesDistinct creates a interface{} set that +// removes the same elements and returns them in their original order. +func InterfacesDistinct(a []interface{}) (set []interface{}) { + set = ameda.InterfacesCopy(a) + ameda.InterfacesDistinct(&set, true) + return set +} + +// SetToInterfaces sets a element to the interface{} set. +func SetToInterfaces(set []interface{}, a interface{}) []interface{} { + return ameda.InterfacesPushDistinct(set, a) +} + +// RemoveFromInterfaces removes the first element from the interface{} set. +func RemoveFromInterfaces(set []interface{}, a interface{}) []interface{} { + ameda.InterfacesRemoveFirst(&set, a) + return set +} + +// RemoveAllFromInterfaces removes all the a element from the interface{} set. +func RemoveAllFromInterfaces(set []interface{}, a interface{}) []interface{} { + ameda.InterfacesRemoveEvery(&set, a) + return set +} diff --git a/vendor/github.com/henrylee2cn/goutil/string.go b/vendor/github.com/andeya/goutil/string.go similarity index 74% rename from vendor/github.com/henrylee2cn/goutil/string.go rename to vendor/github.com/andeya/goutil/string.go index 603b1ba..23b79aa 100644 --- a/vendor/github.com/henrylee2cn/goutil/string.go +++ b/vendor/github.com/andeya/goutil/string.go @@ -5,10 +5,24 @@ import ( "regexp" "strconv" "strings" + "unicode" "unicode/utf8" "unsafe" ) +// Indent inserts prefix at the beginning of each line +func Indent(text, prefix string) string { + if len(prefix) == 0 { + return text + } + has := strings.HasSuffix(text, "\n") + text = prefix + strings.Replace(text, "\n", "\n"+prefix, -1) + if has { + return text[:len(text)-len(prefix)] + } + return text +} + // BytesToString convert []byte type to string type. func BytesToString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) @@ -62,7 +76,123 @@ func CamelString(s string) string { } data = append(data, d) } - return string(data[:]) + return BytesToString(data[:]) +} + +// LintCamelString converts the accepted string to a camel string (xx_id to XxID) +// NOTE: +// support common initialisms +func LintCamelString(name string) string { + // Fast path for simple cases: "_" and all lowercase. + if name == "_" { + return "_" + } + runes := []rune(name) + var i int + for k, v := range runes { + if v != '_' { + i = k + runes[k] = unicode.ToUpper(v) + break + } + } + r := string(toInitialisms(runes[i:])) + return r +} + +func toInitialisms(runes []rune) []rune { + // Split camelCase at any lower->upper transition, and split on underscores. + // Check each word for common initialisms. + w, i := 0, 0 // index of start of word, scan + for i+1 <= len(runes) { + eow := false // whether we hit the end of a word + if i+1 == len(runes) { + eow = true + } else if runes[i+1] == '_' { + // underscore; shift the remainder forward over any run of underscores + eow = true + n := 1 + for i+n+1 < len(runes) && runes[i+n+1] == '_' { + n++ + } + + // Leave at most one underscore if the underscore is between two digits + if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) { + n-- + } + + copy(runes[i+1:], runes[i+n+1:]) + runes = runes[:len(runes)-n] + } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) { + // lower->non-lower + eow = true + } + i++ + if !eow { + continue + } + + // [w,i) is a word. + word := string(runes[w:i]) + if u := strings.ToUpper(word); commonInitialisms[u] { + // Keep consistent case, which is lowercase only at the start. + if w == 0 && unicode.IsLower(runes[w]) { + u = strings.ToLower(u) + } + // All the common initialisms are ASCII, + // so we can replace the bytes exactly. + copy(runes[w:], []rune(u)) + } else if w > 0 && strings.ToLower(word) == word { + // already all lowercase, and not the first word, so uppercase the first character. + runes[w] = unicode.ToUpper(runes[w]) + } + w = i + } + return runes +} + +// commonInitialisms is a set of common initialisms. +// Only add entries that are highly unlikely to be non-initialisms. +// For instance, "ID" is fine (Freudian code is rare), but "AND" is not. +var commonInitialisms = map[string]bool{ + "ACL": true, + "API": true, + "ASCII": true, + "CPU": true, + "CSS": true, + "DNS": true, + "EOF": true, + "GUID": true, + "HTML": true, + "HTTP": true, + "HTTPS": true, + "ID": true, + "IP": true, + "JSON": true, + "LHS": true, + "QPS": true, + "RAM": true, + "RHS": true, + "RPC": true, + "SLA": true, + "SMTP": true, + "SQL": true, + "SSH": true, + "TCP": true, + "TLS": true, + "TTL": true, + "UDP": true, + "UI": true, + "UID": true, + "UUID": true, + "URI": true, + "URL": true, + "UTF8": true, + "VM": true, + "XML": true, + "XMPP": true, + "XSRF": true, + "XSS": true, } var htmlEntityRegexp = regexp.MustCompile(`&#([0-9a-zA-Z]+);*`) diff --git a/vendor/github.com/henrylee2cn/goutil/targz.go b/vendor/github.com/andeya/goutil/targz.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/targz.go rename to vendor/github.com/andeya/goutil/targz.go diff --git a/vendor/github.com/henrylee2cn/goutil/trace.go b/vendor/github.com/andeya/goutil/trace.go similarity index 100% rename from vendor/github.com/henrylee2cn/goutil/trace.go rename to vendor/github.com/andeya/goutil/trace.go diff --git a/vendor/github.com/henrylee2cn/goutil/exported.go b/vendor/github.com/andeya/goutil/type.go similarity index 55% rename from vendor/github.com/henrylee2cn/goutil/exported.go rename to vendor/github.com/andeya/goutil/type.go index c9ae69f..db7f662 100644 --- a/vendor/github.com/henrylee2cn/goutil/exported.go +++ b/vendor/github.com/andeya/goutil/type.go @@ -32,3 +32,25 @@ func ObjectName(obj interface{}) string { } return t.String() } + +// IsCompositionMethod determines whether the method inherits from the anonymous field of the struct. +func IsCompositionMethod(method reflect.Method) bool { + fn := runtime.FuncForPC(method.Func.Pointer()) + file, _ := fn.FileLine(fn.Entry()) + if file != "" { + return false + } + recv := method.Type.In(0) + var found bool + if recv.Kind() == reflect.Ptr { + method, found = recv.Elem().MethodByName(method.Name) + } else { + method, found = reflect.PtrTo(recv).MethodByName(method.Name) + } + if !found { + return true + } + fn = runtime.FuncForPC(method.Func.Pointer()) + file, _ = fn.FileLine(fn.Entry()) + return file == "" +} diff --git a/vendor/github.com/henrylee2cn/ameda/.gitignore b/vendor/github.com/henrylee2cn/ameda/.gitignore new file mode 100644 index 0000000..6857290 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/.gitignore @@ -0,0 +1,21 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +vendor/ + +*.sublime-project +*.sublime-workspace +.DS_Store +.idea +*.zip diff --git a/vendor/github.com/henrylee2cn/ameda/LICENSE b/vendor/github.com/henrylee2cn/ameda/LICENSE new file mode 100644 index 0000000..6346807 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 henrylee2cn + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/henrylee2cn/ameda/README.md b/vendor/github.com/henrylee2cn/ameda/README.md new file mode 100644 index 0000000..27026de --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/README.md @@ -0,0 +1,3 @@ +# ameda [![report card](https://goreportcard.com/badge/github.com/henrylee2cn/ameda?style=flat-square)](http://goreportcard.com/report/henrylee2cn/ameda) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/henrylee2cn/ameda) + +Powerful toolbox for golang data types. diff --git a/vendor/github.com/henrylee2cn/ameda/atoi62.go b/vendor/github.com/henrylee2cn/ameda/atoi62.go new file mode 100644 index 0000000..3129466 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/atoi62.go @@ -0,0 +1,253 @@ +package ameda + +import ( + "errors" + "math" + "strconv" +) + +// ParseUint is like ParseInt but for unsigned numbers. +// NOTE: +// Compatible with standard package strconv. +func ParseUint(s string, base int, bitSize int) (uint64, error) { + // Ignore letter case + if base <= 36 { + return strconv.ParseUint(s, base, bitSize) + } + + const fnParseUint = "ParseUint" + + if base > 62 { + return 0, baseError(fnParseUint, s, base) + } + + if s == "" || !underscoreOK(s) { + return 0, syntaxError(fnParseUint, s) + } + + if bitSize == 0 { + bitSize = int(strconv.IntSize) + } else if bitSize < 0 || bitSize > 64 { + return 0, bitSizeError(fnParseUint, s, bitSize) + } + + // Cutoff is the smallest number such that cutoff*base > maxUint64. + // Use compile-time constants for common cases. + cutoff := math.MaxUint64/uint64(base) + 1 + + maxVal := uint64(1)<= byte(base) { + return 0, syntaxError(fnParseUint, s) + } + + if n >= cutoff { + // n*base overflows + return maxVal, rangeError(fnParseUint, s) + } + n *= uint64(base) + + n1 := n + uint64(d) + if n1 < n || n1 > maxVal { + // n+v overflows + return maxVal, rangeError(fnParseUint, s) + } + n = n1 + } + + return n, nil +} + +// ParseInt interprets a string s in the given base (0, 2 to 62) and +// bit size (0 to 64) and returns the corresponding value i. +// +// If base == 0, the base is implied by the string's prefix: +// base 2 for "0b", base 8 for "0" or "0o", base 16 for "0x", +// and base 10 otherwise. Also, for base == 0 only, underscore +// characters are permitted per the Go integer literal syntax. +// If base is below 0, is 1, or is above 62, an error is returned. +// +// The bitSize argument specifies the integer type +// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 +// correspond to int, int8, int16, int32, and int64. +// If bitSize is below 0 or above 64, an error is returned. +// +// The errors that ParseInt returns have concrete type *NumError +// and include err.Num = s. If s is empty or contains invalid +// digits, err.Err = ErrSyntax and the returned value is 0; +// if the value corresponding to s cannot be represented by a +// signed integer of the given size, err.Err = ErrRange and the +// returned value is the maximum magnitude integer of the +// appropriate bitSize and sign. +// NOTE: +// Compatible with standard package strconv. +func ParseInt(s string, base int, bitSize int) (i int64, err error) { + // Ignore letter case + if base <= 36 { + return strconv.ParseInt(s, base, bitSize) + } + + const fnParseInt = "ParseInt" + + if s == "" { + return 0, syntaxError(fnParseInt, s) + } + + // Pick off leading sign. + s0 := s + neg := false + if s[0] == '+' { + s = s[1:] + } else if s[0] == '-' { + neg = true + s = s[1:] + } + + // Convert unsigned and check range. + var un uint64 + un, err = ParseUint(s, base, bitSize) + if err != nil && err.(*strconv.NumError).Err != strconv.ErrRange { + err.(*strconv.NumError).Func = fnParseInt + err.(*strconv.NumError).Num = s0 + return 0, err + } + + if bitSize == 0 { + bitSize = int(strconv.IntSize) + } + + cutoff := uint64(1 << uint(bitSize-1)) + if !neg && un >= cutoff { + return int64(cutoff - 1), rangeError(fnParseInt, s0) + } + if neg && un > cutoff { + return -int64(cutoff), rangeError(fnParseInt, s0) + } + n := int64(un) + if neg { + n = -n + } + return n, nil +} + +// underscoreOK reports whether the underscores in s are allowed. +// Checking them in this one function lets all the parsers skip over them simply. +// Underscore must appear only between digits or between a base prefix and a digit. +func underscoreOK(s string) bool { + // saw tracks the last character (class) we saw: + // ^ for beginning of number, + // 0 for a digit or base prefix, + // _ for an underscore, + // ! for none of the above. + saw := '^' + i := 0 + + // Optional sign. + if len(s) >= 1 && (s[0] == '-' || s[0] == '+') { + s = s[1:] + } + + // Optional base prefix. + hex := false + if len(s) >= 2 && s[0] == '0' && (lower(s[1]) == 'b' || lower(s[1]) == 'o' || lower(s[1]) == 'x') { + i = 2 + saw = '0' // base prefix counts as a digit for "underscore as digit separator" + hex = lower(s[1]) == 'x' + } + + // Number proper. + for ; i < len(s); i++ { + // Digits are always okay. + if '0' <= s[i] && s[i] <= '9' || hex && 'a' <= lower(s[i]) && lower(s[i]) <= 'f' { + saw = '0' + continue + } + // Underscore must follow digit. + if s[i] == '_' { + if saw != '0' { + return false + } + saw = '_' + continue + } + // Underscore must also be followed by digit. + if saw == '_' { + return false + } + // Saw non-digit, non-underscore. + saw = '!' + } + return saw != '_' +} + +// Atoi is equivalent to ParseInt(s, 10, 0), converted to type int. +func Atoi(s string) (int, error) { + const fnAtoi = "Atoi" + + sLen := len(s) + if strconv.IntSize == 32 && (0 < sLen && sLen < 10) || + strconv.IntSize == 64 && (0 < sLen && sLen < 19) { + // Fast path for small integers that fit int type. + s0 := s + if s[0] == '-' || s[0] == '+' { + s = s[1:] + if len(s) < 1 { + return 0, &strconv.NumError{fnAtoi, s0, strconv.ErrSyntax} + } + } + + n := 0 + for _, ch := range []byte(s) { + ch -= '0' + if ch > 9 { + return 0, &strconv.NumError{fnAtoi, s0, strconv.ErrSyntax} + } + n = n*10 + int(ch) + } + if s0[0] == '-' { + n = -n + } + return n, nil + } + + // Slow path for invalid, big, or underscored integers. + i64, err := ParseInt(s, 10, 0) + if nerr, ok := err.(*strconv.NumError); ok { + nerr.Func = fnAtoi + } + return int(i64), err +} + +// lower(c) is a lower-case letter if and only if +// c is either that lower-case letter or the equivalent upper-case letter. +// Instead of writing c == 'x' || c == 'X' one can write lower(c) == 'x'. +// Note that lower of non-letters can produce other non-letters. +func lower(c byte) byte { + return c | ('x' - 'X') +} +func syntaxError(fn, str string) *strconv.NumError { + return &strconv.NumError{fn, str, strconv.ErrSyntax} +} +func baseError(fn, str string, base int) *strconv.NumError { + return &strconv.NumError{fn, str, errors.New("invalid base " + strconv.Itoa(base))} +} +func rangeError(fn, str string) *strconv.NumError { + return &strconv.NumError{fn, str, strconv.ErrRange} +} +func bitSizeError(fn, str string, bitSize int) *strconv.NumError { + return &strconv.NumError{fn, str, errors.New("invalid bit size " + strconv.Itoa(bitSize))} +} diff --git a/vendor/github.com/henrylee2cn/ameda/atoi_x.go b/vendor/github.com/henrylee2cn/ameda/atoi_x.go new file mode 100644 index 0000000..221d110 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/atoi_x.go @@ -0,0 +1,27 @@ +package ameda + +import ( + "bytes" + "errors" + "fmt" + "math" +) + +// ParseUintByDict convert numStr into corresponding uint64 according to dict. +func ParseUintByDict(dict []byte, numStr string) (uint64, error) { + if len(dict) == 0 { + return 0, errors.New("dict is empty") + } + base := float64(len(dict)) + len := len(numStr) + var number float64 + for i := 0; i < len; i++ { + char := numStr[i : i+1] + pos := bytes.IndexAny(dict, char) + if pos == -1 { + return 0, fmt.Errorf("found a char not included in the dict: %q", char) + } + number = math.Pow(base, float64(len-i-1))*float64(pos) + number + } + return uint64(number), nil +} diff --git a/vendor/github.com/henrylee2cn/ameda/bool.go b/vendor/github.com/henrylee2cn/ameda/bool.go new file mode 100644 index 0000000..ed12802 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/bool.go @@ -0,0 +1,200 @@ +package ameda + +import ( + "strconv" +) + +// BoolToInterface converts bool to interface. +func BoolToInterface(v bool) interface{} { + return v +} + +// BoolToInterfacePtr converts bool to *interface. +func BoolToInterfacePtr(v bool) *interface{} { + r := BoolToInterface(v) + return &r +} + +// BoolToString converts bool to string. +func BoolToString(v bool) string { + return strconv.FormatBool(v) +} + +// BoolToStringPtr converts bool to *string. +func BoolToStringPtr(v bool) *string { + r := BoolToString(v) + return &r +} + +// BoolToBoolPtr converts bool to *bool. +func BoolToBoolPtr(v bool) *bool { + return &v +} + +// BoolToFloat32 converts bool to float32. +func BoolToFloat32(v bool) float32 { + if v { + return 1 + } + return 0 +} + +// BoolToFloat32Ptr converts bool to *float32. +func BoolToFloat32Ptr(v bool) *float32 { + r := BoolToFloat32(v) + return &r +} + +// BoolToFloat64 converts bool to float64. +func BoolToFloat64(v bool) float64 { + if v { + return 1 + } + return 0 +} + +// BoolToFloat64Ptr converts bool to *float64. +func BoolToFloat64Ptr(v bool) *float64 { + r := BoolToFloat64(v) + return &r +} + +// BoolToInt converts bool to int. +func BoolToInt(v bool) int { + if v { + return 1 + } + return 0 +} + +// BoolToIntPtr converts bool to *int. +func BoolToIntPtr(v bool) *int { + r := BoolToInt(v) + return &r +} + +// BoolToInt8 converts bool to int8. +func BoolToInt8(v bool) int8 { + if v { + return 1 + } + return 0 +} + +// BoolToInt8Ptr converts bool to *int8. +func BoolToInt8Ptr(v bool) *int8 { + r := BoolToInt8(v) + return &r +} + +// BoolToInt16 converts bool to int16. +func BoolToInt16(v bool) int16 { + if v { + return 1 + } + return 0 +} + +// BoolToInt16Ptr converts bool to *int16. +func BoolToInt16Ptr(v bool) *int16 { + r := BoolToInt16(v) + return &r +} + +// BoolToInt32 converts bool to int32. +func BoolToInt32(v bool) int32 { + if v { + return 1 + } + return 0 +} + +// BoolToInt32Ptr converts bool to *int32. +func BoolToInt32Ptr(v bool) *int32 { + r := BoolToInt32(v) + return &r +} + +// BoolToInt64 converts bool to int64. +func BoolToInt64(v bool) int64 { + if v { + return 1 + } + return 0 +} + +// BoolToInt64Ptr converts bool to *int64. +func BoolToInt64Ptr(v bool) *int64 { + r := BoolToInt64(v) + return &r +} + +// BoolToUint converts bool to uint. +func BoolToUint(v bool) uint { + if v { + return 1 + } + return 0 +} + +// BoolToUintPtr converts bool to *uint. +func BoolToUintPtr(v bool) *uint { + r := BoolToUint(v) + return &r +} + +// BoolToUint8 converts bool to uint8. +func BoolToUint8(v bool) uint8 { + if v { + return 1 + } + return 0 +} + +// BoolToUint8Ptr converts bool to *uint8. +func BoolToUint8Ptr(v bool) *uint8 { + r := BoolToUint8(v) + return &r +} + +// BoolToUint16 converts bool to uint16. +func BoolToUint16(v bool) uint16 { + if v { + return 1 + } + return 0 +} + +// BoolToUint16Ptr converts bool to *uint16. +func BoolToUint16Ptr(v bool) *uint16 { + r := BoolToUint16(v) + return &r +} + +// BoolToUint32 converts bool to uint32. +func BoolToUint32(v bool) uint32 { + if v { + return 1 + } + return 0 +} + +// BoolToUint32Ptr converts bool to *uint32. +func BoolToUint32Ptr(v bool) *uint32 { + r := BoolToUint32(v) + return &r +} + +// BoolToUint64 converts bool to uint64. +func BoolToUint64(v bool) uint64 { + if v { + return 1 + } + return 0 +} + +// BoolToUint64Ptr converts bool to *uint64. +func BoolToUint64Ptr(v bool) *uint64 { + r := BoolToUint64(v) + return &r +} diff --git a/vendor/github.com/henrylee2cn/ameda/bools.go b/vendor/github.com/henrylee2cn/ameda/bools.go new file mode 100644 index 0000000..1a734c1 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/bools.go @@ -0,0 +1,580 @@ +package ameda + +// OneBool try to return the first element, otherwise return zero value. +func OneBool(b []bool) bool { + if len(b) > 0 { + return b[0] + } + return false +} + +// BoolsCopy creates a copy of the bool slice. +func BoolsCopy(b []bool) []bool { + r := make([]bool, len(b)) + copy(r, b) + return r +} + +// BoolsToInterfaces converts int8 slice to interface slice. +func BoolsToInterfaces(b []bool) []interface{} { + r := make([]interface{}, len(b)) + for k, v := range b { + r[k] = v + } + return r +} + +// BoolsToStrings converts int8 slice to string slice. +func BoolsToStrings(b []bool) []string { + r := make([]string, len(b)) + for k, v := range b { + r[k] = BoolToString(v) + } + return r +} + +// BoolsToFloat32s converts int8 slice to float32 slice. +func BoolsToFloat32s(b []bool) []float32 { + r := make([]float32, len(b)) + for k, v := range b { + r[k] = BoolToFloat32(v) + } + return r +} + +// BoolsToFloat64s converts int8 slice to float64 slice. +func BoolsToFloat64s(b []bool) []float64 { + r := make([]float64, len(b)) + for k, v := range b { + r[k] = BoolToFloat64(v) + } + return r +} + +// BoolsToInts converts int8 slice to int slice. +func BoolsToInts(b []bool) []int { + r := make([]int, len(b)) + for k, v := range b { + r[k] = BoolToInt(v) + } + return r +} + +// BoolsToInt16s converts int8 slice to int16 slice. +func BoolsToInt16s(b []bool) []int16 { + r := make([]int16, len(b)) + for k, v := range b { + r[k] = BoolToInt16(v) + } + return r +} + +// BoolsToInt32s converts int8 slice to int32 slice. +func BoolsToInt32s(b []bool) []int32 { + r := make([]int32, len(b)) + for k, v := range b { + r[k] = BoolToInt32(v) + } + return r +} + +// BoolsToInt64s converts int8 slice to int64 slice. +func BoolsToInt64s(b []bool) []int64 { + r := make([]int64, len(b)) + for k, v := range b { + r[k] = BoolToInt64(v) + } + return r +} + +// BoolsToUints converts bool slice to uint slice. +func BoolsToUints(b []bool) []uint { + r := make([]uint, len(b)) + for k, v := range b { + r[k] = BoolToUint(v) + } + return r +} + +// BoolsToUint8s converts bool slice to uint8 slice. +func BoolsToUint8s(b []bool) []uint8 { + r := make([]uint8, len(b)) + for k, v := range b { + r[k] = BoolToUint8(v) + } + return r +} + +// BoolsToUint16s converts bool slice to uint16 slice. +func BoolsToUint16s(b []bool) []uint16 { + r := make([]uint16, len(b)) + for k, v := range b { + r[k] = BoolToUint16(v) + } + return r +} + +// BoolsToUint32s converts bool slice to uint32 slice. +func BoolsToUint32s(b []bool) []uint32 { + r := make([]uint32, len(b)) + for k, v := range b { + r[k] = BoolToUint32(v) + } + return r +} + +// BoolsToUint64s converts bool slice to uint64 slice. +func BoolsToUint64s(b []bool) []uint64 { + r := make([]uint64, len(b)) + for k, v := range b { + r[k] = BoolToUint64(v) + } + return r +} + +// BoolsCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func BoolsCopyWithin(b []bool, target, start int, end ...int) { + target = fixIndex(len(b), target, true) + if target == len(b) { + return + } + sub := BoolsSlice(b, start, end...) + for k, v := range sub { + b[target+k] = v + } +} + +// BoolsEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func BoolsEvery(b []bool, fn func(b []bool, k int, v bool) bool) bool { + for k, v := range b { + if !fn(b, k, v) { + return false + } + } + return true +} + +// BoolsFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func BoolsFill(b []bool, value bool, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(b), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + b[k] = value + } +} + +// BoolsFilter creates a new slice with all elements that pass the test implemented by the provided function. +func BoolsFilter(b []bool, fn func(b []bool, k int, v bool) bool) []bool { + ret := make([]bool, 0, 16) + for k, v := range b { + if fn(b, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// BoolsFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func BoolsFind(b []bool, fn func(b []bool, k int, v bool) bool) (k int, v bool) { + for k, v := range b { + if fn(b, k, v) { + return k, v + } + } + return -1, false +} + +// BoolsIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func BoolsIncludes(b []bool, valueToFind bool, fromIndex ...int) bool { + return BoolsIndexOf(b, valueToFind, fromIndex...) > -1 +} + +// BoolsIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func BoolsIndexOf(b []bool, searchElement bool, fromIndex ...int) int { + idx := getFromIndex(len(b), fromIndex...) + for k, v := range b[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// BoolsLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func BoolsLastIndexOf(b []bool, searchElement bool, fromIndex ...int) int { + idx := getFromIndex(len(b), fromIndex...) + for k := len(b) - 1; k >= idx; k-- { + if searchElement == b[k] { + return k + } + } + return -1 +} + +// BoolsMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func BoolsMap(b []bool, fn func(b []bool, k int, v bool) bool) []bool { + ret := make([]bool, len(b)) + for k, v := range b { + ret[k] = fn(b, k, v) + } + return ret +} + +// BoolsPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func BoolsPop(b *[]bool) (elem bool, found bool) { + a := *b + if len(a) == 0 { + return false, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *b = a[:len(a):len(a)] + return last, true +} + +// BoolsPush adds one or more elements to the end of an slice and returns the new length of the slice. +func BoolsPush(b *[]bool, element ...bool) int { + *b = append(*b, element...) + return len(*b) +} + +// BoolsPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func BoolsPushDistinct(b []bool, element ...bool) []bool { +L: + for _, v := range element { + for _, vv := range b { + if vv == v { + continue L + } + } + b = append(b, v) + } + return b +} + +// BoolsReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func BoolsReduce( + b []bool, + fn func(b []bool, k int, v, accumulator bool) bool, initialValue ...bool, +) bool { + if len(b) == 0 { + return false + } + start := 0 + acc := b[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(b); k++ { + acc = fn(b, k, b[k], acc) + } + return acc +} + +// BoolsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func BoolsReduceRight( + b []bool, + fn func(b []bool, k int, v, accumulator bool) bool, initialValue ...bool, +) bool { + if len(b) == 0 { + return false + } + end := len(b) - 1 + acc := b[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(b, k, b[k], acc) + } + return acc +} + +// BoolsReverse reverses an slice in place. +func BoolsReverse(b []bool) { + first := 0 + last := len(b) - 1 + for first < last { + b[first], b[last] = b[last], b[first] + first++ + last-- + } +} + +// BoolsShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func BoolsShift(b *[]bool) (element bool, found bool) { + a := *b + if len(a) == 0 { + return false, false + } + first := a[0] + a = a[1:] + *b = a[:len(a):len(a)] + return first, true +} + +// BoolsSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func BoolsSlice(b []bool, begin int, end ...int) []bool { + fixedStart, fixedEnd, ok := fixRange(len(b), begin, end...) + if !ok { + return []bool{} + } + return BoolsCopy(b[fixedStart:fixedEnd]) +} + +// BoolsSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func BoolsSome(b []bool, fn func(b []bool, k int, v bool) bool) bool { + for k, v := range b { + if fn(b, k, v) { + return true + } + } + return false +} + +// BoolsSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func BoolsSplice(b *[]bool, start, deleteCount int, items ...bool) { + a := *b + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := BoolsCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *b = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *b = a[:len(a):len(a)] +} + +// BoolsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func BoolsUnshift(b *[]bool, element ...bool) int { + *b = append(element, *b...) + return len(*b) +} + +// BoolsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func BoolsUnshiftDistinct(b *[]bool, element ...bool) int { + a := *b + if len(element) == 0 { + return len(a) + } + m := make(map[bool]bool, len(element)) + r := make([]bool, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *b = r[:len(r):len(r)] + return len(r) +} + +// BoolsRemoveFirst removes the first matched element from the slice, +// and returns the new length of the slice. +func BoolsRemoveFirst(p *[]bool, elements ...bool) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// BoolsRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func BoolsRemoveEvery(p *[]bool, elements ...bool) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// BoolsConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func BoolsConcat(b ...[]bool) []bool { + var totalLen int + for _, v := range b { + totalLen += len(v) + } + ret := make([]bool, totalLen) + dst := ret + for _, v := range b { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// BoolsIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func BoolsIntersect(b ...[]bool) (intersectCount map[bool]int) { + if len(b) == 0 { + return nil + } + for _, v := range b { + if len(v) == 0 { + return nil + } + } + counts := make([]map[bool]int, len(b)) + for k, v := range b { + counts[k] = boolsDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// BoolsDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func BoolsDistinct(b *[]bool, changeSlice bool) (distinctCount map[bool]int) { + if !changeSlice { + return boolsDistinct(*b, nil) + } + a := (*b)[:0] + distinctCount = boolsDistinct(*b, &a) + n := len(distinctCount) + *b = a[:n:n] + return distinctCount +} + +func boolsDistinct(src []bool, dst *[]bool) map[bool]int { + m := make(map[bool]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} diff --git a/vendor/github.com/henrylee2cn/ameda/float32.go b/vendor/github.com/henrylee2cn/ameda/float32.go new file mode 100644 index 0000000..6bc9e67 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/float32.go @@ -0,0 +1,217 @@ +package ameda + +import ( + "fmt" + "math" +) + +// Float32ToInterface converts float32 to interface. +func Float32ToInterface(v float32) interface{} { + return v +} + +// Float32ToInterfacePtr converts float32 to *interface. +func Float32ToInterfacePtr(v float32) *interface{} { + r := Float32ToInterface(v) + return &r +} + +// Float32ToString converts float32 to string. +func Float32ToString(v float32) string { + return fmt.Sprintf("%f", v) +} + +// Float32ToStringPtr converts float32 to *string. +func Float32ToStringPtr(v float32) *string { + r := Float32ToString(v) + return &r +} + +// Float32ToBool converts float32 to bool. +func Float32ToBool(v float32) bool { + return v != 0 +} + +// Float32ToBoolPtr converts float32 to *bool. +func Float32ToBoolPtr(v float32) *bool { + r := Float32ToBool(v) + return &r +} + +// Float32ToFloat32Ptr converts float32 to *float32. +func Float32ToFloat32Ptr(v float32) *float32 { + return &v +} + +// Float32ToFloat64 converts float32 to float64. +func Float32ToFloat64(v float32) float64 { + return float64(v) +} + +// Float32ToFloat64Ptr converts float32 to *float64. +func Float32ToFloat64Ptr(v float32) *float64 { + r := Float32ToFloat64(v) + return &r +} + +// Float32ToInt converts float32 to int. +func Float32ToInt(v float32) (int, error) { + if Host64bit { + if v > math.MaxInt64 || v < math.MinInt64 { + return 0, errOverflowValue + } + } else { + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errOverflowValue + } + } + return int(v), nil + +} + +// Float32ToInt8 converts float32 to int8. +func Float32ToInt8(v float32) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Float32ToInt8Ptr converts float32 to *int8. +func Float32ToInt8Ptr(v float32) (*int8, error) { + r, err := Float32ToInt8(v) + return &r, err +} + +// Float32ToInt16 converts float32 to int16. +func Float32ToInt16(v float32) (int16, error) { + if v > math.MaxInt16 || v < math.MinInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Float32ToInt16Ptr converts float32 to *int16. +func Float32ToInt16Ptr(v float32) (*int16, error) { + r, err := Float32ToInt16(v) + return &r, err +} + +// Float32ToInt32 converts float32 to int32. +func Float32ToInt32(v float32) (int32, error) { + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// Float32ToInt32Ptr converts float32 to *int32. +func Float32ToInt32Ptr(v float32) (*int32, error) { + r, err := Float32ToInt32(v) + return &r, err +} + +// Float32ToInt64 converts float32 to int64. +func Float32ToInt64(v float32) (int64, error) { + if v > math.MaxInt64 || v < math.MinInt64 { + return 0, errOverflowValue + } + return int64(v), nil +} + +// Float32ToInt64Ptr converts float32 to *int64. +func Float32ToInt64Ptr(v float32) (*int64, error) { + r, err := Float32ToInt64(v) + return &r, err +} + +// Float32ToUint converts float32 to uint. +func Float32ToUint(v float32) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + if Host64bit { + if v > math.MaxUint64 { + return 0, errOverflowValue + } + } else { + if v > math.MaxUint32 { + return 0, errOverflowValue + } + } + return uint(v), nil +} + +// Float32ToUintPtr converts float32 to *uint. +func Float32ToUintPtr(v float32) (*uint, error) { + r, err := Float32ToUint(v) + return &r, err +} + +// Float32ToUint8 converts float32 to uint8. +func Float32ToUint8(v float32) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Float32ToUint8Ptr converts float32 to *uint8. +func Float32ToUint8Ptr(v float32) (*uint8, error) { + r, err := Float32ToUint8(v) + return &r, err +} + +// Float32ToUint16 converts float32 to uint16. +func Float32ToUint16(v float32) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Float32ToUint16Ptr converts float32 to *uint16. +func Float32ToUint16Ptr(v float32) (*uint16, error) { + r, err := Float32ToUint16(v) + return &r, err +} + +// Float32ToUint32 converts float32 to uint32. +func Float32ToUint32(v float32) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint32(v), nil +} + +// Float32ToUint32Ptr converts float32 to *uint32. +func Float32ToUint32Ptr(v float32) (*uint32, error) { + r, err := Float32ToUint32(v) + return &r, err +} + +// Float32ToUint64 converts float32 to uint64. +func Float32ToUint64(v float32) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint64 { + return 0, errOverflowValue + } + return uint64(v), nil +} + +// Float32ToUint64Ptr converts float32 to *uint64. +func Float32ToUint64Ptr(v float32) (*uint64, error) { + r, err := Float32ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/float32s.go b/vendor/github.com/henrylee2cn/ameda/float32s.go new file mode 100644 index 0000000..0aee67e --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/float32s.go @@ -0,0 +1,680 @@ +package ameda + +// OneFloat32 try to return the first element, otherwise return zero value. +func OneFloat32(f []float32) float32 { + if len(f) > 0 { + return f[0] + } + return 0 +} + +// Float32sCopy creates a copy of the float32 slice. +func Float32sCopy(f []float32) []float32 { + b := make([]float32, len(f)) + copy(b, f) + return b +} + +// Float32sToInterfaces converts float32 slice to interface slice. +func Float32sToInterfaces(f []float32) []interface{} { + r := make([]interface{}, len(f)) + for k, v := range f { + r[k] = Float32ToInterface(v) + } + return r +} + +// Float32sToStrings converts float32 slice to string slice. +func Float32sToStrings(f []float32) []string { + r := make([]string, len(f)) + for k, v := range f { + r[k] = Float32ToString(v) + } + return r +} + +// Float32sToBools converts float32 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Float32sToBools(f []float32) []bool { + r := make([]bool, len(f)) + for k, v := range f { + r[k] = Float32ToBool(v) + } + return r +} + +// Float32sToFloat64s converts float32 slice to float64 slice. +func Float32sToFloat64s(f []float32) []float64 { + r := make([]float64, len(f)) + for k, v := range f { + r[k] = Float32ToFloat64(v) + } + return r +} + +// Float32sToInts converts float32 slice to int slice. +func Float32sToInts(f []float32) ([]int, error) { + var err error + r := make([]int, len(f)) + for k, v := range f { + r[k], err = Float32ToInt(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToInt8s converts float32 slice to int8 slice. +func Float32sToInt8s(f []float32) ([]int8, error) { + var err error + r := make([]int8, len(f)) + for k, v := range f { + r[k], err = Float32ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToInt16s converts float32 slice to int16 slice. +func Float32sToInt16s(f []float32) ([]int16, error) { + var err error + r := make([]int16, len(f)) + for k, v := range f { + r[k], err = Float32ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToInt32s converts float32 slice to int32 slice. +func Float32sToInt32s(f []float32) ([]int32, error) { + var err error + r := make([]int32, len(f)) + for k, v := range f { + r[k], err = Float32ToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToInt64s converts float32 slice to int64 slice. +func Float32sToInt64s(f []float32) ([]int64, error) { + var err error + r := make([]int64, len(f)) + for k, v := range f { + r[k], err = Float32ToInt64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToUints converts float32 slice to uint slice. +func Float32sToUints(f []float32) ([]uint, error) { + var err error + r := make([]uint, len(f)) + for k, v := range f { + r[k], err = Float32ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToUint8s converts float32 slice to uint8 slice. +func Float32sToUint8s(f []float32) ([]uint8, error) { + var err error + r := make([]uint8, len(f)) + for k, v := range f { + r[k], err = Float32ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToUint16s converts float32 slice to uint16 slice. +func Float32sToUint16s(f []float32) ([]uint16, error) { + var err error + r := make([]uint16, len(f)) + for k, v := range f { + r[k], err = Float32ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToUint32s converts float32 slice to uint32 slice. +func Float32sToUint32s(f []float32) ([]uint32, error) { + var err error + r := make([]uint32, len(f)) + for k, v := range f { + r[k], err = Float32ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sToUint64s converts float32 slice to uint64 slice. +func Float32sToUint64s(f []float32) ([]uint64, error) { + var err error + r := make([]uint64, len(f)) + for k, v := range f { + r[k], err = Float32ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float32sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Float32sCopyWithin(f []float32, target, start int, end ...int) { + target = fixIndex(len(f), target, true) + if target == len(f) { + return + } + sub := Float32sSlice(f, start, end...) + for k, v := range sub { + f[target+k] = v + } +} + +// Float32sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Float32sEvery(f []float32, fn func(f []float32, k int, v float32) bool) bool { + for k, v := range f { + if !fn(f, k, v) { + return false + } + } + return true +} + +// Float32sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Float32sFill(f []float32, value float32, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(f), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + f[k] = value + } +} + +// Float32sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Float32sFilter(f []float32, fn func(f []float32, k int, v float32) bool) []float32 { + ret := make([]float32, 0) + for k, v := range f { + if fn(f, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Float32sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Float32sFind(f []float32, fn func(f []float32, k int, v float32) bool) (k int, v float32) { + for k, v := range f { + if fn(f, k, v) { + return k, v + } + } + return -1, 0 +} + +// Float32sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float32sIncludes(f []float32, valueToFind float32, fromIndex ...int) bool { + return Float32sIndexOf(f, valueToFind, fromIndex...) > -1 +} + +// Float32sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float32sIndexOf(f []float32, searchElement float32, fromIndex ...int) int { + idx := getFromIndex(len(f), fromIndex...) + for k, v := range f[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Float32sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float32sLastIndexOf(f []float32, searchElement float32, fromIndex ...int) int { + idx := getFromIndex(len(f), fromIndex...) + for k := len(f) - 1; k >= idx; k-- { + if searchElement == f[k] { + return k + } + } + return -1 +} + +// Float32sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Float32sMap(f []float32, fn func(f []float32, k int, v float32) float32) []float32 { + ret := make([]float32, len(f)) + for k, v := range f { + ret[k] = fn(f, k, v) + } + return ret +} + +// Float32sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Float32sPop(f *[]float32) (float32, bool) { + a := *f + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *f = a[:len(a):len(a)] + return last, true +} + +// Float32sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Float32sPush(f *[]float32, element ...float32) int { + *f = append(*f, element...) + return len(*f) +} + +// Float32sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Float32sPushDistinct(f []float32, element ...float32) []float32 { +L: + for _, v := range element { + for _, vv := range f { + if vv == v { + continue L + } + } + f = append(f, v) + } + return f +} + +// Float32sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Float32sReduce( + f []float32, + fn func(f []float32, k int, v, accumulator float32) float32, initialValue ...float32, +) float32 { + if len(f) == 0 { + return 0 + } + start := 0 + acc := f[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(f); k++ { + acc = fn(f, k, f[k], acc) + } + return acc +} + +// Float32sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Float32sReduceRight( + f []float32, + fn func(f []float32, k int, v, accumulator float32) float32, initialValue ...float32, +) float32 { + if len(f) == 0 { + return 0 + } + end := len(f) - 1 + acc := f[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(f, k, f[k], acc) + } + return acc +} + +// Float32sReverse reverses an slice in place. +func Float32sReverse(f []float32) { + first := 0 + last := len(f) - 1 + for first < last { + f[first], f[last] = f[last], f[first] + first++ + last-- + } +} + +// Float32sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Float32sShift(f *[]float32) (float32, bool) { + a := *f + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *f = a[:len(a):len(a)] + return first, true +} + +// Float32sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Float32sSlice(f []float32, begin int, end ...int) []float32 { + fixedStart, fixedEnd, ok := fixRange(len(f), begin, end...) + if !ok { + return []float32{} + } + return Float32sCopy(f[fixedStart:fixedEnd]) +} + +// Float32sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Float32sSome(f []float32, fn func(f []float32, k int, v float32) bool) bool { + for k, v := range f { + if fn(f, k, v) { + return true + } + } + return false +} + +// Float32sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Float32sSplice(f *[]float32, start, deleteCount int, items ...float32) { + a := *f + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Float32sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *f = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *f = a[:len(a):len(a)] +} + +// Float32sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Float32sUnshift(f *[]float32, element ...float32) int { + *f = append(element, *f...) + return len(*f) +} + +// Float32sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Float32sUnshiftDistinct(f *[]float32, element ...float32) int { + a := *f + if len(element) == 0 { + return len(a) + } + m := make(map[float32]bool, len(element)) + r := make([]float32, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *f = r[:len(r):len(r)] + return len(r) +} + +// Float32sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Float32sRemoveFirst(p *[]float32, elements ...float32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Float32sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Float32sRemoveEvery(p *[]float32, elements ...float32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Float32sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Float32sIntersect(f ...[]float32) (intersectCount map[float32]int) { + if len(f) == 0 { + return nil + } + for _, v := range f { + if len(v) == 0 { + return nil + } + } + counts := make([]map[float32]int, len(f)) + for k, v := range f { + counts[k] = float32sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Float32sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Float32sDistinct(f *[]float32, changeSlice bool) (distinctCount map[float32]int) { + if !changeSlice { + return float32sDistinct(*f, nil) + } + a := (*f)[:0] + distinctCount = float32sDistinct(*f, &a) + n := len(distinctCount) + *f = a[:n:n] + return distinctCount +} + +func float32sDistinct(src []float32, dst *[]float32) map[float32]int { + m := make(map[float32]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Float32SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Float32SetUnion(set1, set2 []float32, others ...[]float32) []float32 { + m := make(map[float32]struct{}, len(set1)+len(set2)) + r := make([]float32, 0, len(m)) + for _, set := range append([][]float32{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Float32SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Float32SetIntersect(set1, set2 []float32, others ...[]float32) []float32 { + sets := append([][]float32{set2}, others...) + setsCount := make([]map[float32]int, len(sets)) + for k, v := range sets { + setsCount[k] = float32sDistinct(v, nil) + } + m := make(map[float32]struct{}, len(set1)) + r := make([]float32, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Float32SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Float32SetDifference(set1, set2 []float32, others ...[]float32) []float32 { + m := make(map[float32]struct{}, len(set1)) + r := make([]float32, 0, len(set1)) + sets := append([][]float32{set2}, others...) + for _, v := range sets { + inter := Float32SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/float64.go b/vendor/github.com/henrylee2cn/ameda/float64.go new file mode 100644 index 0000000..e5ea83d --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/float64.go @@ -0,0 +1,220 @@ +package ameda + +import ( + "fmt" + "math" +) + +// Float64ToInterface converts float64 to interface. +func Float64ToInterface(v float64) interface{} { + return v +} + +// Float64ToInterfacePtr converts float64 to *interface. +func Float64ToInterfacePtr(v float64) *interface{} { + r := Float64ToInterface(v) + return &r +} + +// Float64ToString converts float64 to string. +func Float64ToString(v float64) string { + return fmt.Sprintf("%f", v) +} + +// Float64ToStringPtr converts float64 to *string. +func Float64ToStringPtr(v float64) *string { + r := Float64ToString(v) + return &r +} + +// Float64ToBool converts float64 to bool. +func Float64ToBool(v float64) bool { + return v != 0 +} + +// Float64ToBoolPtr converts float64 to *bool. +func Float64ToBoolPtr(v float64) *bool { + r := Float64ToBool(v) + return &r +} + +// Float64ToFloat32 converts float64 to float32. +func Float64ToFloat32(v float64) (float32, error) { + if v > math.MaxFloat32 || v < -math.MaxFloat32 { + return 0, errOverflowValue + } + return float32(v), nil +} + +// Float64ToFloat32Ptr converts float64 to *float32. +func Float64ToFloat32Ptr(v float64) (*float32, error) { + r, err := Float64ToFloat32(v) + return &r, err +} + +// Float64ToFloat64Ptr converts float64 to *float64. +func Float64ToFloat64Ptr(v float64) *float64 { + return &v +} + +// Float64ToInt converts float64 to int. +func Float64ToInt(v float64) (int, error) { + if Host64bit { + if v > math.MaxInt64 || v < math.MinInt64 { + return 0, errOverflowValue + } + } else { + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errOverflowValue + } + } + return int(v), nil + +} + +// Float64ToInt8 converts float64 to int8. +func Float64ToInt8(v float64) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Float64ToInt8Ptr converts float64 to *int8. +func Float64ToInt8Ptr(v float64) (*int8, error) { + r, err := Float64ToInt8(v) + return &r, err +} + +// Float64ToInt16 converts float64 to int16. +func Float64ToInt16(v float64) (int16, error) { + if v > math.MaxInt16 || v < math.MinInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Float64ToInt16Ptr converts float64 to *int16. +func Float64ToInt16Ptr(v float64) (*int16, error) { + r, err := Float64ToInt16(v) + return &r, err +} + +// Float64ToInt32 converts float64 to int32. +func Float64ToInt32(v float64) (int32, error) { + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// Float64ToInt32Ptr converts float64 to *int32. +func Float64ToInt32Ptr(v float64) (*int32, error) { + r, err := Float64ToInt32(v) + return &r, err +} + +// Float64ToInt64 converts float64 to int64. +func Float64ToInt64(v float64) (int64, error) { + if v > math.MaxInt64 || v < math.MinInt64 { + return 0, errOverflowValue + } + return int64(v), nil +} + +// Float64ToInt64Ptr converts float64 to *int64. +func Float64ToInt64Ptr(v float64) (*int64, error) { + r, err := Float64ToInt64(v) + return &r, err +} + +// Float64ToUint converts float64 to uint. +func Float64ToUint(v float64) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + if Host64bit { + if v > math.MaxUint64 { + return 0, errOverflowValue + } + } else { + if v > math.MaxUint32 { + return 0, errOverflowValue + } + } + return uint(v), nil +} + +// Float64ToUintPtr converts float64 to *uint. +func Float64ToUintPtr(v float64) (*uint, error) { + r, err := Float64ToUint(v) + return &r, err +} + +// Float64ToUint8 converts float64 to uint8. +func Float64ToUint8(v float64) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Float64ToUint8Ptr converts float64 to *uint8. +func Float64ToUint8Ptr(v float64) (*uint8, error) { + r, err := Float64ToUint8(v) + return &r, err +} + +// Float64ToUint16 converts float64 to uint16. +func Float64ToUint16(v float64) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Float64ToUint16Ptr converts float64 to *uint16. +func Float64ToUint16Ptr(v float64) (*uint16, error) { + r, err := Float64ToUint16(v) + return &r, err +} + +// Float64ToUint32 converts float64 to uint32. +func Float64ToUint32(v float64) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint32(v), nil +} + +// Float64ToUint32Ptr converts float64 to *uint32. +func Float64ToUint32Ptr(v float64) (*uint32, error) { + r, err := Float64ToUint32(v) + return &r, err +} + +// Float64ToUint64 converts float64 to uint64. +func Float64ToUint64(v float64) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint64 { + return 0, errOverflowValue + } + return uint64(v), nil +} + +// Float64ToUint64Ptr converts float64 to *uint64. +func Float64ToUint64Ptr(v float64) (*uint64, error) { + r, err := Float64ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/float64s.go b/vendor/github.com/henrylee2cn/ameda/float64s.go new file mode 100644 index 0000000..2f456c4 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/float64s.go @@ -0,0 +1,684 @@ +package ameda + +// OneFloat64 try to return the first element, otherwise return zero value. +func OneFloat64(f []float64) float64 { + if len(f) > 0 { + return f[0] + } + return 0 +} + +// Float64sCopy creates a copy of the float64 slice. +func Float64sCopy(f []float64) []float64 { + b := make([]float64, len(f)) + copy(b, f) + return b +} + +// Float64sToInterfaces converts float64 slice to interface slice. +func Float64sToInterfaces(f []float64) []interface{} { + r := make([]interface{}, len(f)) + for k, v := range f { + r[k] = Float64ToInterface(v) + } + return r +} + +// Float64sToStrings converts float64 slice to string slice. +func Float64sToStrings(f []float64) []string { + r := make([]string, len(f)) + for k, v := range f { + r[k] = Float64ToString(v) + } + return r +} + +// Float64sToBools converts float64 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Float64sToBools(f []float64) []bool { + r := make([]bool, len(f)) + for k, v := range f { + r[k] = Float64ToBool(v) + } + return r +} + +// Float64sToFloat32s converts float64 slice to float32 slice. +func Float64sToFloat32s(f []float64) ([]float32, error) { + var err error + r := make([]float32, len(f)) + for k, v := range f { + r[k], err = Float64ToFloat32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToInts converts float64 slice to int slice. +func Float64sToInts(f []float64) ([]int, error) { + var err error + r := make([]int, len(f)) + for k, v := range f { + r[k], err = Float64ToInt(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToInt8s converts float64 slice to int8 slice. +func Float64sToInt8s(f []float64) ([]int8, error) { + var err error + r := make([]int8, len(f)) + for k, v := range f { + r[k], err = Float64ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToInt16s converts float64 slice to int16 slice. +func Float64sToInt16s(f []float64) ([]int16, error) { + var err error + r := make([]int16, len(f)) + for k, v := range f { + r[k], err = Float64ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToInt32s converts float64 slice to int32 slice. +func Float64sToInt32s(f []float64) ([]int32, error) { + var err error + r := make([]int32, len(f)) + for k, v := range f { + r[k], err = Float64ToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToInt64s converts float64 slice to int64 slice. +func Float64sToInt64s(f []float64) ([]int64, error) { + var err error + r := make([]int64, len(f)) + for k, v := range f { + r[k], err = Float64ToInt64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToUints converts float64 slice to uint slice. +func Float64sToUints(f []float64) ([]uint, error) { + var err error + r := make([]uint, len(f)) + for k, v := range f { + r[k], err = Float64ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToUint8s converts float64 slice to uint8 slice. +func Float64sToUint8s(f []float64) ([]uint8, error) { + var err error + r := make([]uint8, len(f)) + for k, v := range f { + r[k], err = Float64ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToUint16s converts float64 slice to uint16 slice. +func Float64sToUint16s(f []float64) ([]uint16, error) { + var err error + r := make([]uint16, len(f)) + for k, v := range f { + r[k], err = Float64ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToUint32s converts float64 slice to uint32 slice. +func Float64sToUint32s(f []float64) ([]uint32, error) { + var err error + r := make([]uint32, len(f)) + for k, v := range f { + r[k], err = Float64ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sToUint64s converts float64 slice to uint64 slice. +func Float64sToUint64s(f []float64) ([]uint64, error) { + var err error + r := make([]uint64, len(f)) + for k, v := range f { + r[k], err = Float64ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Float64sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Float64sCopyWithin(f []float64, target, start int, end ...int) { + target = fixIndex(len(f), target, true) + if target == len(f) { + return + } + sub := Float64sSlice(f, start, end...) + for k, v := range sub { + f[target+k] = v + } +} + +// Float64sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Float64sEvery(f []float64, fn func(f []float64, k int, v float64) bool) bool { + for k, v := range f { + if !fn(f, k, v) { + return false + } + } + return true +} + +// Float64sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Float64sFill(f []float64, value float64, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(f), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + f[k] = value + } +} + +// Float64sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Float64sFilter(f []float64, fn func(f []float64, k int, v float64) bool) []float64 { + ret := make([]float64, 0) + for k, v := range f { + if fn(f, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Float64sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Float64sFind(f []float64, fn func(f []float64, k int, v float64) bool) (k int, v float64) { + for k, v := range f { + if fn(f, k, v) { + return k, v + } + } + return -1, 0 +} + +// Float64sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float64sIncludes(f []float64, valueToFind float64, fromIndex ...int) bool { + return Float64sIndexOf(f, valueToFind, fromIndex...) > -1 +} + +// Float64sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float64sIndexOf(f []float64, searchElement float64, fromIndex ...int) int { + idx := getFromIndex(len(f), fromIndex...) + for k, v := range f[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Float64sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Float64sLastIndexOf(f []float64, searchElement float64, fromIndex ...int) int { + idx := getFromIndex(len(f), fromIndex...) + for k := len(f) - 1; k >= idx; k-- { + if searchElement == f[k] { + return k + } + } + return -1 +} + +// Float64sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Float64sMap(f []float64, fn func(f []float64, k int, v float64) float64) []float64 { + ret := make([]float64, len(f)) + for k, v := range f { + ret[k] = fn(f, k, v) + } + return ret +} + +// Float64sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Float64sPop(f *[]float64) (float64, bool) { + a := *f + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *f = a[:len(a):len(a)] + return last, true +} + +// Float64sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Float64sPush(f *[]float64, element ...float64) int { + *f = append(*f, element...) + return len(*f) +} + +// Float64sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Float64sPushDistinct(f []float64, element ...float64) []float64 { +L: + for _, v := range element { + for _, vv := range f { + if vv == v { + continue L + } + } + f = append(f, v) + } + return f +} + +// Float64sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Float64sReduce( + f []float64, + fn func(f []float64, k int, v, accumulator float64) float64, initialValue ...float64, +) float64 { + if len(f) == 0 { + return 0 + } + start := 0 + acc := f[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(f); k++ { + acc = fn(f, k, f[k], acc) + } + return acc +} + +// Float64sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Float64sReduceRight( + f []float64, + fn func(f []float64, k int, v, accumulator float64) float64, initialValue ...float64, +) float64 { + if len(f) == 0 { + return 0 + } + end := len(f) - 1 + acc := f[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(f, k, f[k], acc) + } + return acc +} + +// Float64sReverse reverses an slice in place. +func Float64sReverse(f []float64) { + first := 0 + last := len(f) - 1 + for first < last { + f[first], f[last] = f[last], f[first] + first++ + last-- + } +} + +// Float64sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Float64sShift(f *[]float64) (float64, bool) { + a := *f + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *f = a[:len(a):len(a)] + return first, true +} + +// Float64sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Float64sSlice(f []float64, begin int, end ...int) []float64 { + fixedStart, fixedEnd, ok := fixRange(len(f), begin, end...) + if !ok { + return []float64{} + } + return Float64sCopy(f[fixedStart:fixedEnd]) +} + +// Float64sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Float64sSome(f []float64, fn func(f []float64, k int, v float64) bool) bool { + for k, v := range f { + if fn(f, k, v) { + return true + } + } + return false +} + +// Float64sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Float64sSplice(f *[]float64, start, deleteCount int, items ...float64) { + a := *f + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Float64sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *f = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *f = a[:len(a):len(a)] +} + +// Float64sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Float64sUnshift(f *[]float64, element ...float64) int { + *f = append(element, *f...) + return len(*f) +} + +// Float64sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Float64sUnshiftDistinct(f *[]float64, element ...float64) int { + a := *f + if len(element) == 0 { + return len(a) + } + m := make(map[float64]bool, len(element)) + r := make([]float64, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *f = r[:len(r):len(r)] + return len(r) +} + +// Float64sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Float64sRemoveFirst(p *[]float64, elements ...float64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Float64sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Float64sRemoveEvery(p *[]float64, elements ...float64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Float64sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Float64sIntersect(f ...[]float64) (intersectCount map[float64]int) { + if len(f) == 0 { + return nil + } + for _, v := range f { + if len(v) == 0 { + return nil + } + } + counts := make([]map[float64]int, len(f)) + for k, v := range f { + counts[k] = float64sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Float64sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Float64sDistinct(f *[]float64, changeSlice bool) (distinctCount map[float64]int) { + if !changeSlice { + return float64sDistinct(*f, nil) + } + a := (*f)[:0] + distinctCount = float64sDistinct(*f, &a) + n := len(distinctCount) + *f = a[:n:n] + return distinctCount +} + +func float64sDistinct(src []float64, dst *[]float64) map[float64]int { + m := make(map[float64]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Float64SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Float64SetUnion(set1, set2 []float64, others ...[]float64) []float64 { + m := make(map[float64]struct{}, len(set1)+len(set2)) + r := make([]float64, 0, len(m)) + for _, set := range append([][]float64{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Float64SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Float64SetIntersect(set1, set2 []float64, others ...[]float64) []float64 { + sets := append([][]float64{set2}, others...) + setsCount := make([]map[float64]int, len(sets)) + for k, v := range sets { + setsCount[k] = float64sDistinct(v, nil) + } + m := make(map[float64]struct{}, len(set1)) + r := make([]float64, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Float64SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Float64SetDifference(set1, set2 []float64, others ...[]float64) []float64 { + m := make(map[float64]struct{}, len(set1)) + r := make([]float64, 0, len(set1)) + sets := append([][]float64{set2}, others...) + for _, v := range sets { + inter := Float64SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/initialize.go b/vendor/github.com/henrylee2cn/ameda/initialize.go new file mode 100644 index 0000000..204a9c5 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/initialize.go @@ -0,0 +1,299 @@ +package ameda + +import ( + "reflect" +) + +// InitPointer initializes nil pointer with zero value. +func InitPointer(v reflect.Value) (done bool) { + for { + kind := v.Kind() + if kind == reflect.Interface { + v = v.Elem() + continue + } + if kind != reflect.Ptr { + return true + } + u := v.Elem() + if u.IsValid() { + v = u + continue + } + if !v.CanSet() { + return false + } + v2 := reflect.New(v.Type().Elem()) + v.Set(v2) + v = v.Elem() + } +} + +// InitString initializes empty string pointer with def. +func InitString(p *string, def string) (done bool) { + if p == nil { + return false + } + if *p == "" { + *p = def + } + return true +} + +// InitBool initializes false bool pointer with def. +func InitBool(p *bool, def bool) (done bool) { + if p == nil { + return false + } + if *p == false { + *p = def + } + return true +} + +// InitByte initializes zero byte pointer with def. +func InitByte(p *byte, def byte) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitInt initializes zero int pointer with def. +func InitInt(p *int, def int) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitInt8 initializes zero int8 pointer with def. +func InitInt8(p *int8, def int8) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitInt16 initializes zero int16 pointer with def. +func InitInt16(p *int16, def int16) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitInt32 initializes zero int32 pointer with def. +func InitInt32(p *int32, def int32) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitInt64 initializes zero int64 pointer with def. +func InitInt64(p *int64, def int64) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitUint initializes zero uint pointer with def. +func InitUint(p *uint, def uint) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitUint8 initializes zero uint8 pointer with def. +func InitUint8(p *uint8, def uint8) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitUint16 initializes zero uint16 pointer with def. +func InitUint16(p *uint16, def uint16) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitUint32 initializes zero uint32 pointer with def. +func InitUint32(p *uint32, def uint32) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitUint64 initializes zero uint64 pointer with def. +func InitUint64(p *uint64, def uint64) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitFloat32 initializes zero float32 pointer with def. +func InitFloat32(p *float32, def float32) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitFloat64 initializes zero float64 pointer with def. +func InitFloat64(p *float64, def float64) (done bool) { + if p == nil { + return false + } + if *p == 0 { + *p = def + } + return true +} + +// InitSampleValue initialize the given type with some non-zero value( "?", $max_number, 0.1, true) +func InitSampleValue(t reflect.Type, maxNestingDeep int) reflect.Value { + if maxNestingDeep <= 0 { + maxNestingDeep = 10 + } + ptrDepth := 0 + for t.Kind() == reflect.Ptr { + t = t.Elem() + ptrDepth++ + } + v := reflect.New(t) + v = initValue(v, 1, maxNestingDeep) + return ReferenceValue(v, ptrDepth-1) +} + +func initValue(v reflect.Value, curDeep int, maxDeep int) reflect.Value { + InitPointer(v) + if curDeep >= maxDeep { + return v + } + var numPtr int + for v.Kind() == reflect.Ptr { + v = v.Elem() + numPtr++ + } + switch v.Kind() { + case reflect.Struct: + curDeep++ + fieldNum := v.Type().NumField() + for i := 0; i < fieldNum; i++ { + e := v.Field(i) + InitPointer(e) + e.Set(initValue(e, curDeep, maxDeep)) + } + case reflect.Slice: + if v.Len() == 0 { + e := reflect.New(v.Type().Elem()) + InitPointer(e) + e = e.Elem() + e = initValue(e, curDeep, maxDeep) + v.Set(reflect.Append(v, e)) + } + case reflect.Array: + if v.Len() > 0 { + e := reflect.New(v.Type().Elem()) + InitPointer(e) + e = e.Elem() + e = initValue(e, curDeep, maxDeep) + v.Index(0).Set(reflect.Append(v, e)) + } + case reflect.Map: + if v.Len() == 0 { + v.Set(reflect.MakeMap(v.Type())) + k := reflect.New(v.Type().Key()) + InitPointer(k) + k = k.Elem() + k = initValue(k, curDeep, maxDeep) + e := reflect.New(v.Type().Elem()) + InitPointer(e) + e = e.Elem() + e = initValue(e, curDeep, maxDeep) + v.SetMapIndex(k, e) + } + case reflect.Int: + if Host32bit { + v.SetInt(-32) + } else { + v.SetInt(-64) + } + case reflect.Int8: + v.SetInt(-8) + case reflect.Int16: + v.SetInt(-16) + case reflect.Int32: + v.SetInt(-32) + case reflect.Int64: + v.SetInt(-64) + case reflect.Uint, reflect.Uintptr: + if Host32bit { + v.SetUint(32) + } else { + v.SetUint(64) + } + case reflect.Uint8: + v.SetUint(8) + case reflect.Uint16: + v.SetUint(16) + case reflect.Uint32: + v.SetUint(32) + case reflect.Uint64: + v.SetUint(64) + case reflect.Float32: + v.SetFloat(-0.32) + case reflect.Float64: + v.SetFloat(-0.64) + case reflect.Bool: + v.SetBool(true) + case reflect.String: + v.SetString("?") + default: + } + return ReferenceValue(v, numPtr) +} diff --git a/vendor/github.com/henrylee2cn/ameda/int.go b/vendor/github.com/henrylee2cn/ameda/int.go new file mode 100644 index 0000000..7e0be14 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int.go @@ -0,0 +1,206 @@ +package ameda + +import ( + "math" + "strconv" +) + +// MaxInt returns max int number for current os. +func MaxInt() int { + if Host32bit { + return math.MaxInt32 + } + return math.MaxInt64 +} + +// IntToInterface converts int to interface. +func IntToInterface(v int) interface{} { + return v +} + +// IntToInterfacePtr converts int to *interface. +func IntToInterfacePtr(v int) *interface{} { + r := IntToInterface(v) + return &r +} + +// IntToString converts int to string. +func IntToString(v int) string { + return strconv.Itoa(v) +} + +// IntToStringPtr converts int to *string. +func IntToStringPtr(v int) *string { + r := IntToString(v) + return &r +} + +// IntToBool converts int to bool. +func IntToBool(v int) bool { + return v != 0 +} + +// IntToBoolPtr converts int to *bool. +func IntToBoolPtr(v int) *bool { + r := IntToBool(v) + return &r +} + +// IntToFloat32 converts int to float32. +func IntToFloat32(v int) float32 { + return float32(v) +} + +// IntToFloat32Ptr converts int to *float32. +func IntToFloat32Ptr(v int) *float32 { + r := IntToFloat32(v) + return &r +} + +// IntToFloat64 converts int to float64. +func IntToFloat64(v int) float64 { + return float64(v) +} + +// IntToFloat64Ptr converts int to *float64. +func IntToFloat64Ptr(v int) *float64 { + r := IntToFloat64(v) + return &r +} + +// IntToIntPtr converts int to *int. +func IntToIntPtr(v int) *int { + return &v +} + +// IntToInt8 converts int to int8. +func IntToInt8(v int) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// IntToInt8Ptr converts int to *int8. +func IntToInt8Ptr(v int) (*int8, error) { + r, err := IntToInt8(v) + return &r, err +} + +// IntToInt16 converts int to int16. +func IntToInt16(v int) (int16, error) { + if v > math.MaxInt16 || v < math.MinInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// IntToInt16Ptr converts int to *int16. +func IntToInt16Ptr(v int) (*int16, error) { + r, err := IntToInt16(v) + return &r, err +} + +// IntToInt32 converts int to int32. +func IntToInt32(v int) (int32, error) { + if Host64bit && (v > math.MaxInt32 || v < math.MinInt32) { + return 0, errOverflowValue + } + return int32(v), nil +} + +// IntToInt32Ptr converts int to *int32. +func IntToInt32Ptr(v int) (*int32, error) { + r, err := IntToInt32(v) + return &r, err +} + +// IntToInt64 converts int to int64. +func IntToInt64(v int) int64 { + return int64(v) +} + +// IntToInt64Ptr converts int to *int64. +func IntToInt64Ptr(v int) *int64 { + r := IntToInt64(v) + return &r +} + +// IntToUint converts int to uint. +func IntToUint(v int) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint(v), nil +} + +// IntToUintPtr converts int to *uint. +func IntToUintPtr(v int) (*uint, error) { + r, err := IntToUint(v) + return &r, err +} + +// IntToUint8 converts int to uint8. +func IntToUint8(v int) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// IntToUint8Ptr converts int to *uint8. +func IntToUint8Ptr(v int) (*uint8, error) { + r, err := IntToUint8(v) + return &r, err +} + +// IntToUint16 converts int to uint16. +func IntToUint16(v int) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// IntToUint16Ptr converts int to *uint16. +func IntToUint16Ptr(v int) (*uint16, error) { + r, err := IntToUint16(v) + return &r, err +} + +// IntToUint32 converts int to uint32. +func IntToUint32(v int) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + if Host64bit && v > int(maxUint32) { + return 0, errOverflowValue + } + return uint32(v), nil +} + +// IntToUint32Ptr converts int to *uint32. +func IntToUint32Ptr(v int) (*uint32, error) { + r, err := IntToUint32(v) + return &r, err +} + +// IntToUint64 converts int to uint64. +func IntToUint64(v int) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint64(v), nil +} + +// IntToUint64Ptr converts int to *uint64. +func IntToUint64Ptr(v int) (*uint64, error) { + r, err := IntToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/int16.go b/vendor/github.com/henrylee2cn/ameda/int16.go new file mode 100644 index 0000000..73513d5 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int16.go @@ -0,0 +1,186 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Int16ToInterface converts int16 to interface. +func Int16ToInterface(v int16) interface{} { + return v +} + +// Int16ToInterfacePtr converts int16 to *interface. +func Int16ToInterfacePtr(v int16) *interface{} { + r := Int16ToInterface(v) + return &r +} + +// Int16ToString converts int16 to string. +func Int16ToString(v int16) string { + return strconv.FormatInt(int64(v), 10) +} + +// Int16ToStringPtr converts int16 to *string. +func Int16ToStringPtr(v int16) *string { + r := Int16ToString(v) + return &r +} + +// Int16ToBool converts int16 to bool. +func Int16ToBool(v int16) bool { + return v != 0 +} + +// Int16ToBoolPtr converts int16 to *bool. +func Int16ToBoolPtr(v int16) *bool { + r := Int16ToBool(v) + return &r +} + +// Int16ToFloat32 converts int16 to float32. +func Int16ToFloat32(v int16) float32 { + return float32(v) +} + +// Int16ToFloat32Ptr converts int16 to *float32. +func Int16ToFloat32Ptr(v int16) *float32 { + r := Int16ToFloat32(v) + return &r +} + +// Int16ToFloat64 converts int16 to float64. +func Int16ToFloat64(v int16) float64 { + return float64(v) +} + +// Int16ToFloat64Ptr converts int16 to *float64. +func Int16ToFloat64Ptr(v int16) *float64 { + r := Int16ToFloat64(v) + return &r +} + +// Int16ToInt converts int16 to int. +func Int16ToInt(v int16) int { + return int(v) +} + +// Int16ToIntPtr converts int16 to *int. +func Int16ToIntPtr(v int16) *int { + r := Int16ToInt(v) + return &r +} + +// Int16ToInt8 converts int16 to int8. +func Int16ToInt8(v int16) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Int16ToInt8Ptr converts int16 to *int8. +func Int16ToInt8Ptr(v int16) (*int8, error) { + r, err := Int16ToInt8(v) + return &r, err +} + +// Int16ToInt16Ptr converts int16 to *int16. +func Int16ToInt16Ptr(v int16) *int16 { + return &v +} + +// Int16ToInt32 converts int16 to int32. +func Int16ToInt32(v int16) int32 { + return int32(v) +} + +// Int16ToInt32Ptr converts int16 to *int32. +func Int16ToInt32Ptr(v int16) *int32 { + r := Int16ToInt32(v) + return &r +} + +// Int16ToInt64 converts int16 to int64. +func Int16ToInt64(v int16) int64 { + return int64(v) +} + +// Int16ToInt64Ptr converts int16 to *int64. +func Int16ToInt64Ptr(v int16) *int64 { + r := Int16ToInt64(v) + return &r +} + +// Int16ToUint converts int16 to uint. +func Int16ToUint(v int16) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint(v), nil +} + +// Int16ToUintPtr converts int16 to *uint. +func Int16ToUintPtr(v int16) (*uint, error) { + r, err := Int16ToUint(v) + return &r, err +} + +// Int16ToUint8 converts int16 to uint8. +func Int16ToUint8(v int16) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Int16ToUint8Ptr converts int16 to *uint8. +func Int16ToUint8Ptr(v int16) (*uint8, error) { + r, err := Int16ToUint8(v) + return &r, err +} + +// Int16ToUint16 converts int16 to uint16. +func Int16ToUint16(v int16) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint16(v), nil +} + +// Int16ToUint16Ptr converts int16 to *uint16. +func Int16ToUint16Ptr(v int16) (*uint16, error) { + r, err := Int16ToUint16(v) + return &r, err +} + +// Int16ToUint32 converts int16 to uint32. +func Int16ToUint32(v int16) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint32(v), nil +} + +// Int16ToUint32Ptr converts int16 to *uint32. +func Int16ToUint32Ptr(v int16) (*uint32, error) { + r, err := Int16ToUint32(v) + return &r, err +} + +// Int16ToUint64 converts int16 to uint64. +func Int16ToUint64(v int16) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint64(v), nil +} + +// Int16ToUint64Ptr converts int16 to *uint64. +func Int16ToUint64Ptr(v int16) (*uint64, error) { + r, err := Int16ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/int16s.go b/vendor/github.com/henrylee2cn/ameda/int16s.go new file mode 100644 index 0000000..13b35e2 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int16s.go @@ -0,0 +1,678 @@ +package ameda + +// OneInt16 try to return the first element, otherwise return zero value. +func OneInt16(i []int16) int16 { + if len(i) > 0 { + return i[0] + } + return 0 +} + +// Int16sCopy creates a copy of the int16 slice. +func Int16sCopy(i []int16) []int16 { + b := make([]int16, len(i)) + copy(b, i) + return b +} + +// Int16sToInterfaces converts int16 slice to interface slice. +func Int16sToInterfaces(i []int16) []interface{} { + r := make([]interface{}, len(i)) + for k, v := range i { + r[k] = v + } + return r +} + +// Int16sToStrings converts int16 slice to string slice. +func Int16sToStrings(i []int16) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = Int16ToString(v) + } + return r +} + +// Int16sToBools converts int16 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Int16sToBools(i []int16) []bool { + r := make([]bool, len(i)) + for k, v := range i { + r[k] = Int16ToBool(v) + } + return r +} + +// Int16sToFloat32s converts int16 slice to float32 slice. +func Int16sToFloat32s(i []int16) []float32 { + r := make([]float32, len(i)) + for k, v := range i { + r[k] = Int16ToFloat32(v) + } + return r +} + +// Int16sToFloat64s converts int16 slice to float64 slice. +func Int16sToFloat64s(i []int16) []float64 { + r := make([]float64, len(i)) + for k, v := range i { + r[k] = Int16ToFloat64(v) + } + return r +} + +// Int16sToInts converts int16 slice to int slice. +func Int16sToInts(i []int16) []int { + r := make([]int, len(i)) + for k, v := range i { + r[k] = Int16ToInt(v) + } + return r +} + +// Int16sToInt8s converts int16 slice to int8 slice. +func Int16sToInt8s(i []int16) ([]int8, error) { + var err error + r := make([]int8, len(i)) + for k, v := range i { + r[k], err = Int16ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sToInt32s converts int16 slice to int32 slice. +func Int16sToInt32s(i []int16) []int32 { + r := make([]int32, len(i)) + for k, v := range i { + r[k] = Int16ToInt32(v) + } + return r +} + +// Int16sToInt64s converts int16 slice to int64 slice. +func Int16sToInt64s(i []int16) []int64 { + r := make([]int64, len(i)) + for k, v := range i { + r[k] = Int16ToInt64(v) + } + return r +} + +// Int16sToUints converts int16 slice to uint slice. +func Int16sToUints(i []int16) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = Int16ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sToUint8s converts int16 slice to uint8 slice. +func Int16sToUint8s(i []int16) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = Int16ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sToUint16s converts int16 slice to uint16 slice. +func Int16sToUint16s(i []int16) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = Int16ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sToUint32s converts int16 slice to uint32 slice. +func Int16sToUint32s(i []int16) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = Int16ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sToUint64s converts int16 slice to uint64 slice. +func Int16sToUint64s(i []int16) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = Int16ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int16sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int16sCopyWithin(i []int16, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := Int16sSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// Int16sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Int16sEvery(i []int16, fn func(i []int16, k int, v int16) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// Int16sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int16sFill(i []int16, value int16, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// Int16sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Int16sFilter(i []int16, fn func(i []int16, k int, v int16) bool) []int16 { + ret := make([]int16, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Int16sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Int16sFind(i []int16, fn func(i []int16, k int, v int16) bool) (k int, v int16) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// Int16sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int16sIncludes(i []int16, valueToFind int16, fromIndex ...int) bool { + return Int16sIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// Int16sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int16sIndexOf(i []int16, searchElement int16, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Int16sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int16sLastIndexOf(i []int16, searchElement int16, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// Int16sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Int16sMap(i []int16, fn func(i []int16, k int, v int16) int16) []int16 { + ret := make([]int16, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// Int16sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Int16sPop(i *[]int16) (int16, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// Int16sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Int16sPush(i *[]int16, element ...int16) int { + *i = append(*i, element...) + return len(*i) +} + +// Int16sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Int16sPushDistinct(i []int16, element ...int16) []int16 { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// Int16sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int16sReduce(i []int16, + fn func(i []int16, k int, v, accumulator int16) int16, initialValue ...int16, +) int16 { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int16sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int16sReduceRight(i []int16, + fn func(i []int16, k int, v, accumulator int16) int16, initialValue ...int16, +) int16 { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int16sReverse reverses an slice in place. +func Int16sReverse(i []int16) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// Int16sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Int16sShift(i *[]int16) (int16, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// Int16sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Int16sSlice(i []int16, begin int, end ...int) []int16 { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []int16{} + } + return Int16sCopy(i[fixedStart:fixedEnd]) +} + +// Int16sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Int16sSome(i []int16, fn func(i []int16, k int, v int16) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// Int16sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Int16sSplice(i *[]int16, start, deleteCount int, items ...int16) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Int16sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// Int16sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Int16sUnshift(i *[]int16, element ...int16) int { + *i = append(element, *i...) + return len(*i) +} + +// Int16sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Int16sUnshiftDistinct(i *[]int16, element ...int16) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[int16]bool, len(element)) + r := make([]int16, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// Int16sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Int16sRemoveFirst(p *[]int16, elements ...int16) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int16sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Int16sRemoveEvery(p *[]int16, elements ...int16) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int16sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Int16sConcat(i ...[]int16) []int16 { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]int16, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Int16sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Int16sIntersect(i ...[]int16) (intersectCount map[int16]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[int16]int, len(i)) + for k, v := range i { + counts[k] = int16sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Int16sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Int16sDistinct(i *[]int16, changeSlice bool) (distinctCount map[int16]int) { + if !changeSlice { + return int16sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = int16sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func int16sDistinct(src []int16, dst *[]int16) map[int16]int { + m := make(map[int16]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Int16SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int16SetUnion(set1, set2 []int16, others ...[]int16) []int16 { + m := make(map[int16]struct{}, len(set1)+len(set2)) + r := make([]int16, 0, len(m)) + for _, set := range append([][]int16{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Int16SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int16SetIntersect(set1, set2 []int16, others ...[]int16) []int16 { + sets := append([][]int16{set2}, others...) + setsCount := make([]map[int16]int, len(sets)) + for k, v := range sets { + setsCount[k] = int16sDistinct(v, nil) + } + m := make(map[int16]struct{}, len(set1)) + r := make([]int16, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Int16SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Int16SetDifference(set1, set2 []int16, others ...[]int16) []int16 { + m := make(map[int16]struct{}, len(set1)) + r := make([]int16, 0, len(set1)) + sets := append([][]int16{set2}, others...) + for _, v := range sets { + inter := Int16SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/int32.go b/vendor/github.com/henrylee2cn/ameda/int32.go new file mode 100644 index 0000000..6719926 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int32.go @@ -0,0 +1,192 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Int32ToInterface converts int32 to interface. +func Int32ToInterface(v int32) interface{} { + return v +} + +// Int32ToInterfacePtr converts int32 to *interface. +func Int32ToInterfacePtr(v int32) *interface{} { + r := Int32ToInterface(v) + return &r +} + +// Int32ToString converts int32 to string. +func Int32ToString(v int32) string { + return strconv.FormatInt(int64(v), 10) +} + +// Int32ToStringPtr converts int32 to *string. +func Int32ToStringPtr(v int32) *string { + r := Int32ToString(v) + return &r +} + +// Int32ToBool converts int32 to bool. +func Int32ToBool(v int32) bool { + return v != 0 +} + +// Int32ToBoolPtr converts int32 to *bool. +func Int32ToBoolPtr(v int32) *bool { + r := Int32ToBool(v) + return &r +} + +// Int32ToFloat32 converts int32 to float32. +func Int32ToFloat32(v int32) float32 { + return float32(v) +} + +// Int32ToFloat32Ptr converts int32 to *float32. +func Int32ToFloat32Ptr(v int32) *float32 { + r := Int32ToFloat32(v) + return &r +} + +// Int32ToFloat64 converts int32 to float64. +func Int32ToFloat64(v int32) float64 { + return float64(v) +} + +// Int32ToFloat64Ptr converts int32 to *float64. +func Int32ToFloat64Ptr(v int32) *float64 { + r := Int32ToFloat64(v) + return &r +} + +// Int32ToInt converts int32 to int. +func Int32ToInt(v int32) int { + return int(v) +} + +// Int32ToIntPtr converts int32 to *int. +func Int32ToIntPtr(v int32) *int { + r := Int32ToInt(v) + return &r +} + +// Int32ToInt8 converts int32 to int8. +func Int32ToInt8(v int32) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Int32ToInt8Ptr converts int32 to *int8. +func Int32ToInt8Ptr(v int32) (*int8, error) { + r, err := Int32ToInt8(v) + return &r, err +} + +// Int32ToInt16 converts int32 to int16. +func Int32ToInt16(v int32) (int16, error) { + if v > math.MaxInt16 || v < math.MinInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Int32ToInt16Ptr converts int32 to *int16. +func Int32ToInt16Ptr(v int32) (*int16, error) { + r, err := Int32ToInt16(v) + return &r, err +} + +// Int32ToInt32Ptr converts int32 to *int32. +func Int32ToInt32Ptr(v int32) *int32 { + return &v +} + +// Int32ToInt64 converts int32 to int64. +func Int32ToInt64(v int32) int64 { + return int64(v) +} + +// Int32ToInt64Ptr converts int32 to *int64. +func Int32ToInt64Ptr(v int32) *int64 { + r := Int32ToInt64(v) + return &r +} + +// Int32ToUint converts int32 to uint. +func Int32ToUint(v int32) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint(v), nil +} + +// Int32ToUintPtr converts int32 to *uint. +func Int32ToUintPtr(v int32) (*uint, error) { + r, err := Int32ToUint(v) + return &r, err +} + +// Int32ToUint8 converts int32 to uint8. +func Int32ToUint8(v int32) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Int32ToUint8Ptr converts int32 to *uint8. +func Int32ToUint8Ptr(v int32) (*uint8, error) { + r, err := Int32ToUint8(v) + return &r, err +} + +// Int32ToUint16 converts int32 to uint16. +func Int32ToUint16(v int32) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Int32ToUint16Ptr converts int32 to *uint16. +func Int32ToUint16Ptr(v int32) (*uint16, error) { + r, err := Int32ToUint16(v) + return &r, err +} + +// Int32ToUint32 converts int32 to uint32. +func Int32ToUint32(v int32) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint32(v), nil +} + +// Int32ToUint32Ptr converts int32 to *uint32. +func Int32ToUint32Ptr(v int32) (*uint32, error) { + r, err := Int32ToUint32(v) + return &r, err +} + +// Int32ToUint64 converts int32 to uint64. +func Int32ToUint64(v int32) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint64(v), nil +} + +// Int32ToUint64Ptr converts int32 to *uint64. +func Int32ToUint64Ptr(v int32) (*uint64, error) { + r, err := Int32ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/int32s.go b/vendor/github.com/henrylee2cn/ameda/int32s.go new file mode 100644 index 0000000..0b32f47 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int32s.go @@ -0,0 +1,682 @@ +package ameda + +// OneInt32 try to return the first element, otherwise return zero value. +func OneInt32(i []int32) int32 { + if len(i) > 0 { + return i[0] + } + return 0 +} + +// Int32sCopy creates a copy of the int32 slice. +func Int32sCopy(i []int32) []int32 { + b := make([]int32, len(i)) + copy(b, i) + return b +} + +// Int32sToInterfaces converts int32 slice to interface slice. +func Int32sToInterfaces(i []int32) []interface{} { + r := make([]interface{}, len(i)) + for k, v := range i { + r[k] = Int32ToInterface(v) + } + return r +} + +// Int32sToStrings converts int32 slice to string slice. +func Int32sToStrings(i []int32) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = Int32ToString(v) + } + return r +} + +// Int32sToBools converts int32 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Int32sToBools(i []int32) []bool { + r := make([]bool, len(i)) + for k, v := range i { + r[k] = Int32ToBool(v) + } + return r +} + +// Int32sToFloat32s converts int32 slice to float32 slice. +func Int32sToFloat32s(i []int32) []float32 { + r := make([]float32, len(i)) + for k, v := range i { + r[k] = Int32ToFloat32(v) + } + return r +} + +// Int32sToFloat64s converts int32 slice to float64 slice. +func Int32sToFloat64s(i []int32) []float64 { + r := make([]float64, len(i)) + for k, v := range i { + r[k] = Int32ToFloat64(v) + } + return r +} + +// Int32sToInts converts int32 slice to int slice. +func Int32sToInts(i []int32) []int { + r := make([]int, len(i)) + for k, v := range i { + r[k] = Int32ToInt(v) + } + return r +} + +// Int32sToInt8s converts int32 slice to int8 slice. +func Int32sToInt8s(i []int32) ([]int8, error) { + var err error + r := make([]int8, len(i)) + for k, v := range i { + r[k], err = Int32ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToInt16s converts int32 slice to int16 slice. +func Int32sToInt16s(i []int32) ([]int16, error) { + var err error + r := make([]int16, len(i)) + for k, v := range i { + r[k], err = Int32ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToInt64s converts int32 slice to int64 slice. +func Int32sToInt64s(i []int32) []int64 { + r := make([]int64, len(i)) + for k, v := range i { + r[k] = Int32ToInt64(v) + } + return r +} + +// Int32sToUints converts int32 slice to uint slice. +func Int32sToUints(i []int32) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = Int32ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToUint8s converts int32 slice to uint8 slice. +func Int32sToUint8s(i []int32) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = Int32ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToUint16s converts int32 slice to uint16 slice. +func Int32sToUint16s(i []int32) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = Int32ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToUint32s converts int32 slice to uint32 slice. +func Int32sToUint32s(i []int32) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = Int32ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sToUint64s converts int32 slice to uint64 slice. +func Int32sToUint64s(i []int32) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = Int32ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int32sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int32sCopyWithin(i []int32, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := Int32sSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// Int32sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Int32sEvery(i []int32, fn func(i []int32, k int, v int32) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// Int32sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int32sFill(i []int32, value int32, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// Int32sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Int32sFilter(i []int32, fn func(i []int32, k int, v int32) bool) []int32 { + ret := make([]int32, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Int32sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Int32sFind(i []int32, fn func(i []int32, k int, v int32) bool) (k int, v int32) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// Int32sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int32sIncludes(i []int32, valueToFind int32, fromIndex ...int) bool { + return Int32sIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// Int32sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int32sIndexOf(i []int32, searchElement int32, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Int32sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int32sLastIndexOf(i []int32, searchElement int32, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// Int32sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Int32sMap(i []int32, fn func(i []int32, k int, v int32) int32) []int32 { + ret := make([]int32, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// Int32sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Int32sPop(i *[]int32) (int32, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// Int32sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Int32sPush(i *[]int32, element ...int32) int { + *i = append(*i, element...) + return len(*i) +} + +// Int32sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Int32sPushDistinct(i []int32, element ...int32) []int32 { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// Int32sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int32sReduce(i []int32, + fn func(i []int32, k int, v, accumulator int32) int32, initialValue ...int32, +) int32 { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int32sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int32sReduceRight(i []int32, + fn func(i []int32, k int, v, accumulator int32) int32, initialValue ...int32, +) int32 { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int32sReverse reverses an slice in place. +func Int32sReverse(i []int32) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// Int32sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Int32sShift(i *[]int32) (int32, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// Int32sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Int32sSlice(i []int32, begin int, end ...int) []int32 { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []int32{} + } + return Int32sCopy(i[fixedStart:fixedEnd]) +} + +// Int32sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Int32sSome(i []int32, fn func(i []int32, k int, v int32) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// Int32sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Int32sSplice(i *[]int32, start, deleteCount int, items ...int32) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Int32sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// Int32sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Int32sUnshift(i *[]int32, element ...int32) int { + *i = append(element, *i...) + return len(*i) +} + +// Int32sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Int32sUnshiftDistinct(i *[]int32, element ...int32) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[int32]bool, len(element)) + r := make([]int32, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// Int32sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Int32sRemoveFirst(p *[]int32, elements ...int32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int32sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Int32sRemoveEvery(p *[]int32, elements ...int32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int32sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Int32sConcat(i ...[]int32) []int32 { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]int32, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Int32sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Int32sIntersect(i ...[]int32) (intersectCount map[int32]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[int32]int, len(i)) + for k, v := range i { + counts[k] = int32sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Int32sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Int32sDistinct(i *[]int32, changeSlice bool) (distinctCount map[int32]int) { + if !changeSlice { + return int32sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = int32sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func int32sDistinct(src []int32, dst *[]int32) map[int32]int { + m := make(map[int32]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Int32SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int32SetUnion(set1, set2 []int32, others ...[]int32) []int32 { + m := make(map[int32]struct{}, len(set1)+len(set2)) + r := make([]int32, 0, len(m)) + for _, set := range append([][]int32{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Int32SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int32SetIntersect(set1, set2 []int32, others ...[]int32) []int32 { + sets := append([][]int32{set2}, others...) + setsCount := make([]map[int32]int, len(sets)) + for k, v := range sets { + setsCount[k] = int32sDistinct(v, nil) + } + m := make(map[int32]struct{}, len(set1)) + r := make([]int32, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Int32SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Int32SetDifference(set1, set2 []int32, others ...[]int32) []int32 { + m := make(map[int32]struct{}, len(set1)) + r := make([]int32, 0, len(set1)) + sets := append([][]int32{set2}, others...) + for _, v := range sets { + inter := Int32SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/int64.go b/vendor/github.com/henrylee2cn/ameda/int64.go new file mode 100644 index 0000000..c04e746 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int64.go @@ -0,0 +1,201 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Int64ToInterface converts int64 to interface. +func Int64ToInterface(v int64) interface{} { + return v +} + +// Int64ToInterfacePtr converts int64 to *interface. +func Int64ToInterfacePtr(v int64) *interface{} { + r := Int64ToInterface(v) + return &r +} + +// Int64ToString converts int64 to string. +func Int64ToString(v int64) string { + return strconv.FormatInt(v, 10) +} + +// Int64ToStringPtr converts int64 to *string. +func Int64ToStringPtr(v int64) *string { + r := Int64ToString(v) + return &r +} + +// Int64ToBool converts int64 to bool. +func Int64ToBool(v int64) bool { + return v != 0 +} + +// Int64ToBoolPtr converts int64 to *bool. +func Int64ToBoolPtr(v int64) *bool { + r := Int64ToBool(v) + return &r +} + +// Int64ToFloat32 converts int64 to float32. +func Int64ToFloat32(v int64) float32 { + return float32(v) +} + +// Int64ToFloat32Ptr converts int64 to *float32. +func Int64ToFloat32Ptr(v int64) *float32 { + r := Int64ToFloat32(v) + return &r +} + +// Int64ToFloat64 converts int64 to float64. +func Int64ToFloat64(v int64) float64 { + return float64(v) +} + +// Int64ToFloat64Ptr converts int64 to *float64. +func Int64ToFloat64Ptr(v int64) *float64 { + r := Int64ToFloat64(v) + return &r +} + +// Int64ToInt converts int64 to int. +func Int64ToInt(v int64) (int, error) { + if !Host64bit && v > math.MaxInt32 { + return 0, errOverflowValue + } + return int(v), nil +} + +// Int64ToIntPtr converts int64 to *int. +func Int64ToIntPtr(v int64) (*int, error) { + r, err := Int64ToInt(v) + return &r, err +} + +// Int64ToInt8 converts int64 to int8. +func Int64ToInt8(v int64) (int8, error) { + if v > math.MaxInt8 || v < math.MinInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Int64ToInt8Ptr converts int64 to *int8. +func Int64ToInt8Ptr(v int64) (*int8, error) { + r, err := Int64ToInt8(v) + return &r, err +} + +// Int64ToInt16 converts int64 to int16. +func Int64ToInt16(v int64) (int16, error) { + if v > math.MaxInt16 || v < math.MinInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Int64ToInt16Ptr converts int64 to *int16. +func Int64ToInt16Ptr(v int64) (*int16, error) { + r, err := Int64ToInt16(v) + return &r, err +} + +// Int64ToInt32 converts int64 to int32. +func Int64ToInt32(v int64) (int32, error) { + if v > math.MaxInt32 || v < math.MinInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// Int64ToInt32Ptr converts int64 to *int32. +func Int64ToInt32Ptr(v int64) (*int32, error) { + r, err := Int64ToInt32(v) + return &r, err +} + +// Int64ToInt64Ptr converts int64 to *int64. +func Int64ToInt64Ptr(v int64) *int64 { + return &v +} + +// Int64ToUint converts int64 to uint. +func Int64ToUint(v int64) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + if !Host64bit && v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint(v), nil +} + +// Int64ToUintPtr converts int64 to *uint. +func Int64ToUintPtr(v int64) (*uint, error) { + r, err := Int64ToUint(v) + return &r, err +} + +// Int64ToUint8 converts int64 to uint8. +func Int64ToUint8(v int64) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Int64ToUint8Ptr converts int64 to *uint8. +func Int64ToUint8Ptr(v int64) (*uint8, error) { + r, err := Int64ToUint8(v) + return &r, err +} + +// Int64ToUint16 converts int64 to uint16. +func Int64ToUint16(v int64) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Int64ToUint16Ptr converts int64 to *uint16. +func Int64ToUint16Ptr(v int64) (*uint16, error) { + r, err := Int64ToUint16(v) + return &r, err +} + +// Int64ToUint32 converts int64 to uint32. +func Int64ToUint32(v int64) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint32(v), nil +} + +// Int64ToUint32Ptr converts int64 to *uint32. +func Int64ToUint32Ptr(v int64) (*uint32, error) { + r, err := Int64ToUint32(v) + return &r, err +} + +// Int64ToUint64 converts int64 to uint64. +func Int64ToUint64(v int64) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint64(v), nil +} + +// Int64ToUint64Ptr converts int64 to *uint64. +func Int64ToUint64Ptr(v int64) (*uint64, error) { + r, err := Int64ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/int64s.go b/vendor/github.com/henrylee2cn/ameda/int64s.go new file mode 100644 index 0000000..6e62c55 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int64s.go @@ -0,0 +1,692 @@ +package ameda + +// OneInt64 try to return the first element, otherwise return zero value. +func OneInt64(i []int64) int64 { + if len(i) > 0 { + return i[0] + } + return 0 +} + +// Int64sCopy creates a copy of the int64 slice. +func Int64sCopy(i []int64) []int64 { + b := make([]int64, len(i)) + copy(b, i) + return b +} + +// Int64sToInterfaces converts int64 slice to interface slice. +func Int64sToInterfaces(i []int64) []interface{} { + r := make([]interface{}, len(i)) + for k, v := range i { + r[k] = Int64ToInterface(v) + } + return r +} + +// Int64sToStrings converts int64 slice to string slice. +func Int64sToStrings(i []int64) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = Int64ToString(v) + } + return r +} + +// Int64sToBools converts int64 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Int64sToBools(i []int64) []bool { + r := make([]bool, len(i)) + for k, v := range i { + r[k] = Int64ToBool(v) + } + return r +} + +// Int64sToFloat32s converts int64 slice to float32 slice. +func Int64sToFloat32s(i []int64) []float32 { + r := make([]float32, len(i)) + for k, v := range i { + r[k] = Int64ToFloat32(v) + } + return r +} + +// Int64sToFloat64s converts int64 slice to float64 slice. +func Int64sToFloat64s(i []int64) []float64 { + r := make([]float64, len(i)) + for k, v := range i { + r[k] = Int64ToFloat64(v) + } + return r +} + +// Int64sToInts converts int64 slice to int slice. +func Int64sToInts(i []int64) ([]int, error) { + var err error + r := make([]int, len(i)) + for k, v := range i { + r[k], err = Int64ToInt(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToInt8s converts int64 slice to int8 slice. +func Int64sToInt8s(i []int64) ([]int8, error) { + var err error + r := make([]int8, len(i)) + for k, v := range i { + r[k], err = Int64ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToInt16s converts int64 slice to int16 slice. +func Int64sToInt16s(i []int64) ([]int16, error) { + var err error + r := make([]int16, len(i)) + for k, v := range i { + r[k], err = Int64ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToInt32s converts int64 slice to int32 slice. +func Int64sToInt32s(i []int64) ([]int32, error) { + var err error + r := make([]int32, len(i)) + for k, v := range i { + r[k], err = Int64ToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToUints converts int64 slice to uint slice. +func Int64sToUints(i []int64) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = Int64ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToUint8s converts int64 slice to uint8 slice. +func Int64sToUint8s(i []int64) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = Int64ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToUint16s converts int64 slice to uint16 slice. +func Int64sToUint16s(i []int64) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = Int64ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToUint32s converts int64 slice to uint32 slice. +func Int64sToUint32s(i []int64) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = Int64ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sToUint64s converts int64 slice to uint64 slice. +func Int64sToUint64s(i []int64) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = Int64ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int64sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int64sCopyWithin(i []int64, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := Int64sSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// Int64sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Int64sEvery(i []int64, fn func(i []int64, k int, v int64) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// Int64sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int64sFill(i []int64, value int64, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// Int64sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Int64sFilter(i []int64, fn func(i []int64, k int, v int64) bool) []int64 { + ret := make([]int64, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Int64sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Int64sFind(i []int64, fn func(i []int64, k int, v int64) bool) (k int, v int64) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// Int64sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int64sIncludes(i []int64, valueToFind int64, fromIndex ...int) bool { + return Int64sIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// Int64sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int64sIndexOf(i []int64, searchElement int64, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Int64sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int64sLastIndexOf(i []int64, searchElement int64, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// Int64sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Int64sMap(i []int64, fn func(i []int64, k int, v int64) int64) []int64 { + ret := make([]int64, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// Int64sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Int64sPop(i *[]int64) (int64, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// Int64sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Int64sPush(i *[]int64, element ...int64) int { + *i = append(*i, element...) + return len(*i) +} + +// Int64sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Int64sPushDistinct(i []int64, element ...int64) []int64 { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// Int64sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int64sReduce( + i []int64, + fn func(i []int64, k int, v, accumulator int64) int64, initialValue ...int64, +) int64 { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int64sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int64sReduceRight( + i []int64, + fn func(i []int64, k int, v, accumulator int64) int64, initialValue ...int64, +) int64 { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int64sReverse reverses an slice in place. +func Int64sReverse(i []int64) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// Int64sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Int64sShift(i *[]int64) (int64, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// Int64sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Int64sSlice(i []int64, begin int, end ...int) []int64 { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []int64{} + } + return Int64sCopy(i[fixedStart:fixedEnd]) +} + +// Int64sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Int64sSome(i []int64, fn func(i []int64, k int, v int64) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// Int64sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Int64sSplice(i *[]int64, start, deleteCount int, items ...int64) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Int64sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// Int64sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Int64sUnshift(i *[]int64, element ...int64) int { + *i = append(element, *i...) + return len(*i) +} + +// Int64sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Int64sUnshiftDistinct(i *[]int64, element ...int64) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[int64]bool, len(element)) + r := make([]int64, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// Int64sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Int64sRemoveFirst(p *[]int64, elements ...int64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int64sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Int64sRemoveEvery(p *[]int64, elements ...int64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int64sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Int64sConcat(i ...[]int64) []int64 { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]int64, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Int64sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Int64sIntersect(i ...[]int64) (intersectCount map[int64]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[int64]int, len(i)) + for k, v := range i { + counts[k] = int64sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Int64sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Int64sDistinct(i *[]int64, changeSlice bool) (distinctCount map[int64]int) { + if !changeSlice { + return int64sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = int64sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func int64sDistinct(src []int64, dst *[]int64) map[int64]int { + m := make(map[int64]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Int64SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int64SetUnion(set1, set2 []int64, others ...[]int64) []int64 { + m := make(map[int64]struct{}, len(set1)+len(set2)) + r := make([]int64, 0, len(m)) + for _, set := range append([][]int64{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Int64SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int64SetIntersect(set1, set2 []int64, others ...[]int64) []int64 { + sets := append([][]int64{set2}, others...) + setsCount := make([]map[int64]int, len(sets)) + for k, v := range sets { + setsCount[k] = int64sDistinct(v, nil) + } + m := make(map[int64]struct{}, len(set1)) + r := make([]int64, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Int64SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Int64SetDifference(set1, set2 []int64, others ...[]int64) []int64 { + m := make(map[int64]struct{}, len(set1)) + r := make([]int64, 0, len(set1)) + sets := append([][]int64{set2}, others...) + for _, v := range sets { + inter := Int64SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/int8.go b/vendor/github.com/henrylee2cn/ameda/int8.go new file mode 100644 index 0000000..5c89c97 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int8.go @@ -0,0 +1,179 @@ +package ameda + +import ( + "strconv" +) + +// Int8ToInterface converts int8 to interface. +func Int8ToInterface(v int8) interface{} { + return v +} + +// Int8ToInterfacePtr converts int8 to *interface. +func Int8ToInterfacePtr(v int8) *interface{} { + r := Int8ToInterface(v) + return &r +} + +// Int8ToString converts int8 to string. +func Int8ToString(v int8) string { + return strconv.FormatInt(int64(v), 10) +} + +// Int8ToStringPtr converts int8 to *string. +func Int8ToStringPtr(v int8) *string { + r := Int8ToString(v) + return &r +} + +// Int8ToBool converts int8 to bool. +func Int8ToBool(v int8) bool { + return v != 0 +} + +// Int8ToBoolPtr converts int8 to *bool. +func Int8ToBoolPtr(v int8) *bool { + r := Int8ToBool(v) + return &r +} + +// Int8ToFloat32 converts int8 to float32. +func Int8ToFloat32(v int8) float32 { + return float32(v) +} + +// Int8ToFloat32Ptr converts int8 to *float32. +func Int8ToFloat32Ptr(v int8) *float32 { + r := Int8ToFloat32(v) + return &r +} + +// Int8ToFloat64 converts int8 to float64. +func Int8ToFloat64(v int8) float64 { + return float64(v) +} + +// Int8ToFloat64Ptr converts int8 to *float64. +func Int8ToFloat64Ptr(v int8) *float64 { + r := Int8ToFloat64(v) + return &r +} + +// Int8ToInt converts int8 to int. +func Int8ToInt(v int8) int { + return int(v) +} + +// Int8ToIntPtr converts int8 to *int. +func Int8ToIntPtr(v int8) *int { + r := Int8ToInt(v) + return &r +} + +// Int8ToInt8Ptr converts int8 to *int8. +func Int8ToInt8Ptr(v int8) *int8 { + return &v +} + +// Int8ToInt16 converts int8 to int16. +func Int8ToInt16(v int8) int16 { + return int16(v) +} + +// Int8ToInt16Ptr converts int8 to *int16. +func Int8ToInt16Ptr(v int8) *int16 { + r := Int8ToInt16(v) + return &r +} + +// Int8ToInt32 converts int8 to int32. +func Int8ToInt32(v int8) int32 { + return int32(v) +} + +// Int8ToInt32Ptr converts int8 to *int32. +func Int8ToInt32Ptr(v int8) *int32 { + r := Int8ToInt32(v) + return &r +} + +// Int8ToInt64 converts int8 to int64. +func Int8ToInt64(v int8) int64 { + return int64(v) +} + +// Int8ToInt64Ptr converts int8 to *int64. +func Int8ToInt64Ptr(v int8) *int64 { + r := Int8ToInt64(v) + return &r +} + +// Int8ToUint converts int8 to uint. +func Int8ToUint(v int8) (uint, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint(v), nil +} + +// Int8ToUintPtr converts int8 to *uint. +func Int8ToUintPtr(v int8) (*uint, error) { + r, err := Int8ToUint(v) + return &r, err +} + +// Int8ToUint8 converts int8 to uint8. +func Int8ToUint8(v int8) (uint8, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint8(v), nil +} + +// Int8ToUint8Ptr converts int8 to *uint8. +func Int8ToUint8Ptr(v int8) (*uint8, error) { + r, err := Int8ToUint8(v) + return &r, err +} + +// Int8ToUint16 converts int8 to uint16. +func Int8ToUint16(v int8) (uint16, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint16(v), nil +} + +// Int8ToUint16Ptr converts int8 to *uint16. +func Int8ToUint16Ptr(v int8) (*uint16, error) { + r, err := Int8ToUint16(v) + return &r, err +} + +// Int8ToUint32 converts int8 to uint32. +func Int8ToUint32(v int8) (uint32, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint32(v), nil +} + +// Int8ToUint32Ptr converts int8 to *uint32. +func Int8ToUint32Ptr(v int8) (*uint32, error) { + r, err := Int8ToUint32(v) + return &r, err +} + +// Int8ToUint64 converts int8 to uint64. +func Int8ToUint64(v int8) (uint64, error) { + if v < 0 { + return 0, errNegativeValue + } + return uint64(v), nil +} + +// Int8ToUint64Ptr converts int8 to *uint64. +func Int8ToUint64Ptr(v int8) (*uint64, error) { + r, err := Int8ToUint64(v) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/int8s.go b/vendor/github.com/henrylee2cn/ameda/int8s.go new file mode 100644 index 0000000..1189b55 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/int8s.go @@ -0,0 +1,679 @@ +package ameda + +// OneInt8 try to return the first element, otherwise return zero value. +func OneInt8(i []int8) int8 { + if len(i) > 0 { + return i[0] + } + return 0 +} + +// Int8sCopy creates a copy of the int8 slice. +func Int8sCopy(i []int8) []int8 { + b := make([]int8, len(i)) + copy(b, i) + return b +} + +// Int8sToInterfaces converts int8 slice to interface slice. +func Int8sToInterfaces(i []int8) []interface{} { + r := make([]interface{}, len(i)) + for k, v := range i { + r[k] = v + } + return r +} + +// Int8sToStrings converts int8 slice to string slice. +func Int8sToStrings(i []int8) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = Int8ToString(v) + } + return r +} + +// Int8sToBools converts int8 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Int8sToBools(i []int8) []bool { + r := make([]bool, len(i)) + for k, v := range i { + r[k] = Int8ToBool(v) + } + return r +} + +// Int8sToFloat32s converts int8 slice to float32 slice. +func Int8sToFloat32s(i []int8) []float32 { + r := make([]float32, len(i)) + for k, v := range i { + r[k] = Int8ToFloat32(v) + } + return r +} + +// Int8sToFloat64s converts int8 slice to float64 slice. +func Int8sToFloat64s(i []int8) []float64 { + r := make([]float64, len(i)) + for k, v := range i { + r[k] = Int8ToFloat64(v) + } + return r +} + +// Int8sToInts converts int8 slice to int slice. +func Int8sToInts(i []int8) []int { + r := make([]int, len(i)) + for k, v := range i { + r[k] = Int8ToInt(v) + } + return r +} + +// Ints converts int8 slice to int slice. +func Int8sInts(i []int8) []int { + return Int8sToInts(i) +} + +// Int8sToInt16s converts int8 slice to int16 slice. +func Int8sToInt16s(i []int8) []int16 { + r := make([]int16, len(i)) + for k, v := range i { + r[k] = Int8ToInt16(v) + } + return r +} + +// Int8sToInt32s converts int8 slice to int32 slice. +func Int8sToInt32s(i []int8) []int32 { + r := make([]int32, len(i)) + for k, v := range i { + r[k] = Int8ToInt32(v) + } + return r +} + +// Int8sToInt64s converts int8 slice to int64 slice. +func Int8sToInt64s(i []int8) []int64 { + r := make([]int64, len(i)) + for k, v := range i { + r[k] = Int8ToInt64(v) + } + return r +} + +// Int8sToUints converts int8 slice to uint slice. +func Int8sToUints(i []int8) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = Int8ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int8sToUint8s converts int8 slice to uint8 slice. +func Int8sToUint8s(i []int8) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = Int8ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int8sToUint16s converts int8 slice to uint16 slice. +func Int8sToUint16s(i []int8) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = Int8ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int8sToUint32s converts int8 slice to uint32 slice. +func Int8sToUint32s(i []int8) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = Int8ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int8sToUint64s converts int8 slice to uint64 slice. +func Int8sToUint64s(i []int8) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = Int8ToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Int8sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int8sCopyWithin(i []int8, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := Int8sSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// Int8sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Int8sEvery(i []int8, fn func(i []int8, k int, v int8) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// Int8sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Int8sFill(i []int8, value int8, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// Int8sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Int8sFilter(i []int8, fn func(i []int8, k int, v int8) bool) []int8 { + ret := make([]int8, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Int8sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Int8sFind(i []int8, fn func(i []int8, k int, v int8) bool) (k int, v int8) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// Int8sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int8sIncludes(i []int8, valueToFind int8, fromIndex ...int) bool { + return Int8sIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// Int8sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int8sIndexOf(i []int8, searchElement int8, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Int8sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Int8sLastIndexOf(i []int8, searchElement int8, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// Int8sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Int8sMap(i []int8, fn func(i []int8, k int, v int8) int8) []int8 { + ret := make([]int8, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// Int8sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Int8sPop(i *[]int8) (int8, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// Int8sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Int8sPush(i *[]int8, element ...int8) int { + *i = append(*i, element...) + return len(*i) +} + +// Int8sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Int8sPushDistinct(i []int8, element ...int8) []int8 { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// Int8sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int8sReduce(i []int8, + fn func(i []int8, k int, v, accumulator int8) int8, initialValue ...int8, +) int8 { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int8sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Int8sReduceRight(i []int8, + fn func(i []int8, k int, v, accumulator int8) int8, initialValue ...int8, +) int8 { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// Int8sReverse reverses an slice in place. +func Int8sReverse(i []int8) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// Int8sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Int8sShift(i *[]int8) (int8, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// Int8sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Int8sSlice(i []int8, begin int, end ...int) []int8 { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []int8{} + } + return Int8sCopy(i[fixedStart:fixedEnd]) +} + +// Int8sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Int8sSome(i []int8, fn func(i []int8, k int, v int8) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// Int8sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Int8sSplice(i *[]int8, start, deleteCount int, items ...int8) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Int8sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// Int8sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Int8sUnshift(i *[]int8, element ...int8) int { + *i = append(element, *i...) + return len(*i) +} + +// Int8sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Int8sUnshiftDistinct(i *[]int8, element ...int8) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[int8]bool, len(element)) + r := make([]int8, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// Int8sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Int8sRemoveFirst(p *[]int8, elements ...int8) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int8sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Int8sRemoveEvery(p *[]int8, elements ...int8) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Int8sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Int8sConcat(i ...[]int8) []int8 { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]int8, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Int8sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Int8sIntersect(i ...[]int8) (intersectCount map[int8]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[int8]int, len(i)) + for k, v := range i { + counts[k] = int8sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Int8sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Int8sDistinct(i *[]int8, changeSlice bool) (distinctCount map[int8]int) { + if !changeSlice { + return int8sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = int8sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func int8sDistinct(src []int8, dst *[]int8) map[int8]int { + m := make(map[int8]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Int8SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int8SetUnion(set1, set2 []int8, others ...[]int8) []int8 { + m := make(map[int8]struct{}, len(set1)+len(set2)) + r := make([]int8, 0, len(m)) + for _, set := range append([][]int8{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Int8SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Int8SetIntersect(set1, set2 []int8, others ...[]int8) []int8 { + sets := append([][]int8{set2}, others...) + setsCount := make([]map[int8]int, len(sets)) + for k, v := range sets { + setsCount[k] = int8sDistinct(v, nil) + } + m := make(map[int8]struct{}, len(set1)) + r := make([]int8, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Int8SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Int8SetDifference(set1, set2 []int8, others ...[]int8) []int8 { + m := make(map[int8]struct{}, len(set1)) + r := make([]int8, 0, len(set1)) + sets := append([][]int8{set2}, others...) + for _, v := range sets { + inter := Int8SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/interface.go b/vendor/github.com/henrylee2cn/ameda/interface.go new file mode 100644 index 0000000..1805a47 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/interface.go @@ -0,0 +1,812 @@ +package ameda + +import ( + "fmt" + "reflect" +) + +// InterfaceToInterfacePtr converts interface to *interface. +func InterfaceToInterfacePtr(i interface{}) *interface{} { + return &i +} + +// InterfaceToString converts interface to string. +func InterfaceToString(i interface{}) string { + return fmt.Sprintf("%v", i) +} + +// InterfaceToStringPtr converts interface to *string. +func InterfaceToStringPtr(i interface{}) *string { + v := InterfaceToString(i) + return &v +} + +// InterfaceToBool converts interface to bool. +// NOTE: +// 0 is false, other numbers are true +func InterfaceToBool(i interface{}, emptyAsFalse ...bool) (bool, error) { + switch v := i.(type) { + case bool: + return v, nil + case nil: + return false, nil + case float32: + return Float32ToBool(v), nil + case float64: + return Float64ToBool(v), nil + case int: + return IntToBool(v), nil + case int8: + return Int8ToBool(v), nil + case int16: + return Int16ToBool(v), nil + case int32: + return Int32ToBool(v), nil + case int64: + return Int64ToBool(v), nil + case uint: + return UintToBool(v), nil + case uint8: + return Uint8ToBool(v), nil + case uint16: + return Uint16ToBool(v), nil + case uint32: + return Uint32ToBool(v), nil + case uint64: + return Uint64ToBool(v), nil + case uintptr: + return v != 0, nil + case string: + return StringToBool(v, emptyAsFalse...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return r.Bool(), nil + case reflect.Invalid: + return false, nil + case reflect.Float32, reflect.Float64: + return Float64ToBool(r.Float()), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToBool(r.Int()), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToBool(r.Uint()), nil + case reflect.String: + return StringToBool(r.String(), emptyAsFalse...) + } + if isEmptyAsZero(emptyAsFalse) { + return !isZero(r), nil + } + return false, fmt.Errorf("cannot convert %#v of type %T to bool", i, i) + } +} + +// InterfaceToBoolPtr converts interface to *bool. +// NOTE: +// 0 is false, other numbers are true +func InterfaceToBoolPtr(i interface{}, emptyAsFalse ...bool) (*bool, error) { + r, err := InterfaceToBool(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToFloat32 converts interface to float32. +func InterfaceToFloat32(i interface{}, emptyStringAsZero ...bool) (float32, error) { + switch v := i.(type) { + case bool: + return BoolToFloat32(v), nil + case nil: + return 0, nil + case int: + return IntToFloat32(v), nil + case int8: + return Int8ToFloat32(v), nil + case int16: + return Int16ToFloat32(v), nil + case int32: + return Int32ToFloat32(v), nil + case int64: + return Int64ToFloat32(v), nil + case uint: + return UintToFloat32(v), nil + case uint8: + return Uint8ToFloat32(v), nil + case uint16: + return Uint16ToFloat32(v), nil + case uint32: + return Uint32ToFloat32(v), nil + case uint64: + return Uint64ToFloat32(v), nil + case uintptr: + return UintToFloat32(uint(v)), nil + case string: + return StringToFloat32(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToFloat32(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32: + return float32(r.Float()), nil + case reflect.Float64: + return Float64ToFloat32(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToFloat32(r.Int()), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToFloat32(r.Uint()), nil + case reflect.String: + return StringToFloat32(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToFloat32(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to float32", i, i) + } +} + +// InterfaceToFloat32Ptr converts interface to *float32. +func InterfaceToFloat32Ptr(i interface{}, emptyAsFalse ...bool) (*float32, error) { + r, err := InterfaceToFloat32(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToFloat64 converts interface to float64. +func InterfaceToFloat64(i interface{}, emptyStringAsZero ...bool) (float64, error) { + switch v := i.(type) { + case bool: + return BoolToFloat64(v), nil + case nil: + return 0, nil + case int: + return IntToFloat64(v), nil + case int8: + return Int8ToFloat64(v), nil + case int16: + return Int16ToFloat64(v), nil + case int32: + return Int32ToFloat64(v), nil + case int64: + return Int64ToFloat64(v), nil + case uint: + return UintToFloat64(v), nil + case uint8: + return Uint8ToFloat64(v), nil + case uint16: + return Uint16ToFloat64(v), nil + case uint32: + return Uint32ToFloat64(v), nil + case uint64: + return Uint64ToFloat64(v), nil + case uintptr: + return UintToFloat64(uint(v)), nil + case string: + return StringToFloat64(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToFloat64(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return r.Float(), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToFloat64(r.Int()), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToFloat64(r.Uint()), nil + case reflect.String: + return StringToFloat64(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToFloat64(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to float64", i, i) + } +} + +// InterfaceToFloat64Ptr converts interface to *float64. +func InterfaceToFloat64Ptr(i interface{}, emptyAsFalse ...bool) (*float64, error) { + r, err := InterfaceToFloat64(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToInt converts interface to int. +func InterfaceToInt(i interface{}, emptyStringAsZero ...bool) (int, error) { + switch v := i.(type) { + case bool: + return BoolToInt(v), nil + case nil: + return 0, nil + case int: + return v, nil + case int8: + return Int8ToInt(v), nil + case int16: + return Int16ToInt(v), nil + case int32: + return Int32ToInt(v), nil + case int64: + return Int64ToInt(v) + case uint: + return UintToInt(v) + case uint8: + return Uint8ToInt(v), nil + case uint16: + return Uint16ToInt(v), nil + case uint32: + return Uint32ToInt(v), nil + case uint64: + return Uint64ToInt(v), nil + case uintptr: + return UintToInt(uint(v)) + case string: + return StringToInt(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToInt(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToInt(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToInt(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToInt(r.Uint()), nil + case reflect.String: + return StringToInt(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToInt(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to int", i, i) + } +} + +// InterfaceToIntPtr converts interface to *float64. +func InterfaceToIntPtr(i interface{}, emptyAsFalse ...bool) (*int, error) { + r, err := InterfaceToInt(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToInt8 converts interface to int8. +func InterfaceToInt8(i interface{}, emptyStringAsZero ...bool) (int8, error) { + switch v := i.(type) { + case bool: + return BoolToInt8(v), nil + case nil: + return 0, nil + case int: + return IntToInt8(v) + case int8: + return v, nil + case int16: + return Int16ToInt8(v) + case int32: + return Int32ToInt8(v) + case int64: + return Int64ToInt8(v) + case uint: + return UintToInt8(v) + case uint8: + return Uint8ToInt8(v) + case uint16: + return Uint16ToInt8(v) + case uint32: + return Uint32ToInt8(v) + case uint64: + return Uint64ToInt8(v) + case uintptr: + return UintToInt8(uint(v)) + case string: + return StringToInt8(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToInt8(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToInt8(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToInt8(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToInt8(r.Uint()) + case reflect.String: + return StringToInt8(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToInt8(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to int8", i, i) + } +} + +// InterfaceToInt8Ptr converts interface to *int8. +func InterfaceToInt8Ptr(i interface{}, emptyAsFalse ...bool) (*int8, error) { + r, err := InterfaceToInt8(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToInt16 converts interface to int16. +func InterfaceToInt16(i interface{}, emptyStringAsZero ...bool) (int16, error) { + switch v := i.(type) { + case bool: + return BoolToInt16(v), nil + case nil: + return 0, nil + case int: + return IntToInt16(v) + case int8: + return Int8ToInt16(v), nil + case int16: + return v, nil + case int32: + return Int32ToInt16(v) + case int64: + return Int64ToInt16(v) + case uint: + return UintToInt16(v) + case uint8: + return Uint8ToInt16(v), nil + case uint16: + return Uint16ToInt16(v) + case uint32: + return Uint32ToInt16(v) + case uint64: + return Uint64ToInt16(v) + case uintptr: + return UintToInt16(uint(v)) + case string: + return StringToInt16(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToInt16(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToInt16(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToInt16(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToInt16(r.Uint()) + case reflect.String: + return StringToInt16(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToInt16(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to int16", i, i) + } +} + +// InterfaceToInt16Ptr converts interface to *int16. +func InterfaceToInt16Ptr(i interface{}, emptyAsFalse ...bool) (*int16, error) { + r, err := InterfaceToInt16(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToInt32 converts interface to int32. +func InterfaceToInt32(i interface{}, emptyStringAsZero ...bool) (int32, error) { + switch v := i.(type) { + case bool: + return BoolToInt32(v), nil + case nil: + return 0, nil + case int: + return IntToInt32(v) + case int8: + return Int8ToInt32(v), nil + case int16: + return Int16ToInt32(v), nil + case int32: + return v, nil + case int64: + return Int64ToInt32(v) + case uint: + return UintToInt32(v) + case uint8: + return Uint8ToInt32(v), nil + case uint16: + return Uint16ToInt32(v), nil + case uint32: + return Uint32ToInt32(v) + case uint64: + return Uint64ToInt32(v) + case uintptr: + return UintToInt32(uint(v)) + case string: + return StringToInt32(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToInt32(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToInt32(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToInt32(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToInt32(r.Uint()) + case reflect.String: + return StringToInt32(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToInt32(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to int32", i, i) + } +} + +// InterfaceToInt32Ptr converts interface to *int32. +func InterfaceToInt32Ptr(i interface{}, emptyAsFalse ...bool) (*int32, error) { + r, err := InterfaceToInt32(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToInt64 converts interface to int64. +func InterfaceToInt64(i interface{}, emptyStringAsZero ...bool) (int64, error) { + switch v := i.(type) { + case bool: + return BoolToInt64(v), nil + case nil: + return 0, nil + case int: + return IntToInt64(v), nil + case int8: + return Int8ToInt64(v), nil + case int16: + return Int16ToInt64(v), nil + case int32: + return Int32ToInt64(v), nil + case int64: + return v, nil + case uint: + return UintToInt64(v) + case uint8: + return Uint8ToInt64(v), nil + case uint16: + return Uint16ToInt64(v), nil + case uint32: + return Uint32ToInt64(v), nil + case uint64: + return Uint64ToInt64(v) + case uintptr: + return UintToInt64(uint(v)) + case string: + return StringToInt64(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToInt64(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToInt64(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return r.Int(), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToInt64(r.Uint()) + case reflect.String: + return StringToInt64(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToInt64(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to int64", i, i) + } +} + +// InterfaceToInt64Ptr converts interface to *int64. +func InterfaceToInt64Ptr(i interface{}, emptyAsFalse ...bool) (*int64, error) { + r, err := InterfaceToInt64(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToUint converts interface to uint. +func InterfaceToUint(i interface{}, emptyStringAsZero ...bool) (uint, error) { + switch v := i.(type) { + case bool: + return BoolToUint(v), nil + case nil: + return 0, nil + case int: + return IntToUint(v) + case int8: + return Int8ToUint(v) + case int16: + return Int16ToUint(v) + case int32: + return Int32ToUint(v) + case int64: + return Int64ToUint(v) + case uint: + return v, nil + case uint8: + return Uint8ToUint(v), nil + case uint16: + return Uint16ToUint(v), nil + case uint32: + return Uint32ToUint(v), nil + case uint64: + return Uint64ToUint(v) + case uintptr: + return uint(v), nil + case string: + return StringToUint(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToUint(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToUint(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToUint(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToUint(r.Uint()) + case reflect.String: + return StringToUint(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToUint(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to uint", i, i) + } +} + +// InterfaceToUintPtr converts interface to *uint. +func InterfaceToUintPtr(i interface{}, emptyAsFalse ...bool) (*uint, error) { + r, err := InterfaceToUint(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToUint8 converts interface to uint8. +func InterfaceToUint8(i interface{}, emptyStringAsZero ...bool) (uint8, error) { + switch v := i.(type) { + case bool: + return BoolToUint8(v), nil + case nil: + return 0, nil + case int: + return IntToUint8(v) + case int8: + return Int8ToUint8(v) + case int16: + return Int16ToUint8(v) + case int32: + return Int32ToUint8(v) + case int64: + return Int64ToUint8(v) + case uint: + return UintToUint8(v) + case uint8: + return v, nil + case uint16: + return Uint16ToUint8(v) + case uint32: + return Uint32ToUint8(v) + case uint64: + return Uint64ToUint8(v) + case uintptr: + return UintToUint8(uint(v)) + case string: + return StringToUint8(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToUint8(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToUint8(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToUint8(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToUint8(r.Uint()) + case reflect.String: + return StringToUint8(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToUint8(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to uint8", i, i) + } +} + +// InterfaceToUint8Ptr converts interface to *uint8. +func InterfaceToUint8Ptr(i interface{}, emptyAsFalse ...bool) (*uint8, error) { + r, err := InterfaceToUint8(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToUint16 converts interface to uint16. +func InterfaceToUint16(i interface{}, emptyStringAsZero ...bool) (uint16, error) { + switch v := i.(type) { + case bool: + return BoolToUint16(v), nil + case nil: + return 0, nil + case int: + return IntToUint16(v) + case int8: + return Int8ToUint16(v) + case int16: + return Int16ToUint16(v) + case int32: + return Int32ToUint16(v) + case int64: + return Int64ToUint16(v) + case uint: + return UintToUint16(v) + case uint8: + return Uint8ToUint16(v), nil + case uint16: + return v, nil + case uint32: + return Uint32ToUint16(v) + case uint64: + return Uint64ToUint16(v) + case uintptr: + return UintToUint16(uint(v)) + case string: + return StringToUint16(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToUint16(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToUint16(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToUint16(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToUint16(r.Uint()) + case reflect.String: + return StringToUint16(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToUint16(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to uint16", i, i) + } +} + +// InterfaceToUint16Ptr converts interface to *uint16. +func InterfaceToUint16Ptr(i interface{}, emptyAsFalse ...bool) (*uint16, error) { + r, err := InterfaceToUint16(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToUint32 converts interface to uint32. +func InterfaceToUint32(i interface{}, emptyStringAsZero ...bool) (uint32, error) { + switch v := i.(type) { + case bool: + return BoolToUint32(v), nil + case nil: + return 0, nil + case int: + return IntToUint32(v) + case int8: + return Int8ToUint32(v) + case int16: + return Int16ToUint32(v) + case int32: + return Int32ToUint32(v) + case int64: + return Int64ToUint32(v) + case uint: + return UintToUint32(v) + case uint8: + return Uint8ToUint32(v), nil + case uint16: + return Uint16ToUint32(v), nil + case uint32: + return v, nil + case uint64: + return Uint64ToUint32(v) + case uintptr: + return UintToUint32(uint(v)) + case string: + return StringToUint32(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToUint32(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToUint32(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToUint32(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return Uint64ToUint32(r.Uint()) + case reflect.String: + return StringToUint32(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToUint32(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to uint32", i, i) + } +} + +// InterfaceToUint32Ptr converts interface to *uint32. +func InterfaceToUint32Ptr(i interface{}, emptyAsFalse ...bool) (*uint32, error) { + r, err := InterfaceToUint32(i, emptyAsFalse...) + return &r, err +} + +// InterfaceToUint64 converts interface to uint64. +func InterfaceToUint64(i interface{}, emptyStringAsZero ...bool) (uint64, error) { + switch v := i.(type) { + case bool: + return BoolToUint64(v), nil + case nil: + return 0, nil + case int: + return IntToUint64(v) + case int8: + return Int8ToUint64(v) + case int16: + return Int16ToUint64(v) + case int32: + return Int32ToUint64(v) + case int64: + return Int64ToUint64(v) + case uint: + return UintToUint64(v), nil + case uint8: + return Uint8ToUint64(v), nil + case uint16: + return Uint16ToUint64(v), nil + case uint32: + return Uint32ToUint64(v), nil + case uint64: + return v, nil + case uintptr: + return UintToUint64(uint(v)), nil + case string: + return StringToUint64(v, emptyStringAsZero...) + default: + r := IndirectValue(reflect.ValueOf(i)) + switch r.Kind() { + case reflect.Bool: + return BoolToUint64(r.Bool()), nil + case reflect.Invalid: + return 0, nil + case reflect.Float32, reflect.Float64: + return Float64ToUint64(r.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return Int64ToUint64(r.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return r.Uint(), nil + case reflect.String: + return StringToUint64(r.String(), emptyStringAsZero...) + } + if isEmptyAsZero(emptyStringAsZero) { + return BoolToUint64(!isZero(r)), nil + } + return 0, fmt.Errorf("cannot convert %#v of type %T to uint64", i, i) + } +} + +// InterfaceToUint64Ptr converts interface to *uint64. +func InterfaceToUint64Ptr(i interface{}, emptyAsFalse ...bool) (*uint64, error) { + r, err := InterfaceToUint64(i, emptyAsFalse...) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/interfaces.go b/vendor/github.com/henrylee2cn/ameda/interfaces.go new file mode 100644 index 0000000..5a1135f --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/interfaces.go @@ -0,0 +1,643 @@ +package ameda + +// OneInterface try to return the first element, otherwise return zero value. +func OneInterface(i []interface{}) interface{} { + if len(i) > 0 { + return i[0] + } + return nil +} + +// InterfacesCopy creates a copy of the interface slice. +func InterfacesCopy(i []interface{}) []interface{} { + b := make([]interface{}, len(i)) + copy(b, i) + return b +} + +// InterfacesToStrings converts interface slice to string slice. +func InterfacesToStrings(i []interface{}) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = InterfaceToString(v) + } + return r +} + +// InterfacesToBools converts interface slice to bool slice. +// NOTE: +// 0 is false, other numbers are true +func InterfacesToBools(i []interface{}) ([]bool, error) { + var err error + r := make([]bool, len(i)) + for k, v := range i { + r[k], err = InterfaceToBool(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToFloat32s converts interface slice to float32 slice. +func InterfacesToFloat32s(i []interface{}) ([]float32, error) { + var err error + r := make([]float32, len(i)) + for k, v := range i { + r[k], err = InterfaceToFloat32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToFloat64s converts interface slice to float64 slice. +func InterfacesToFloat64s(i []interface{}) ([]float64, error) { + var err error + r := make([]float64, len(i)) + for k, v := range i { + r[k], err = InterfaceToFloat64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToInts converts interface slice to int slice. +func InterfacesToInts(i []interface{}) ([]int, error) { + var err error + r := make([]int, len(i)) + for k, v := range i { + r[k], err = InterfaceToInt(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToInt8s converts interface slice to int8 slice. +func InterfacesToInt8s(i []interface{}) ([]int8, error) { + var err error + r := make([]int8, len(i)) + for k, v := range i { + r[k], err = InterfaceToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToInt16s converts interface slice to int16 slice. +func InterfacesToInt16s(i []interface{}) ([]int16, error) { + var err error + r := make([]int16, len(i)) + for k, v := range i { + r[k], err = InterfaceToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToInt32s converts interface slice to int32 slice. +func InterfacesToInt32s(i []interface{}) ([]int32, error) { + var err error + r := make([]int32, len(i)) + for k, v := range i { + r[k], err = InterfaceToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToInt64s converts interface slice to int64 slice. +func InterfacesToInt64s(i []interface{}) ([]int64, error) { + var err error + r := make([]int64, len(i)) + for k, v := range i { + r[k], err = InterfaceToInt64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToUints converts interface slice to uint slice. +func InterfacesToUints(i []interface{}) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = InterfaceToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToUint8s converts interface slice to uint8 slice. +func InterfacesToUint8s(i []interface{}) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = InterfaceToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToUint16s converts interface slice to uint16 slice. +func InterfacesToUint16s(i []interface{}) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = InterfaceToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToUint32s converts interface slice to uint32 slice. +func InterfacesToUint32s(i []interface{}) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = InterfaceToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesToUint64s converts interface slice to uint64 slice. +func InterfacesToUint64s(i []interface{}) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = InterfaceToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// InterfacesCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func InterfacesCopyWithin(i []interface{}, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := InterfacesSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// InterfacesEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func InterfacesEvery(i []interface{}, fn func(i []interface{}, k int, v interface{}) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// InterfacesFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func InterfacesFill(i []interface{}, value []interface{}, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// InterfacesFilter creates a new slice with all elements that pass the test implemented by the provided function. +func InterfacesFilter(i []interface{}, fn func(i []interface{}, k int, v interface{}) bool) []interface{} { + ret := make([]interface{}, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// InterfacesFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func InterfacesFind(i []interface{}, fn func(i []interface{}, k int, v interface{}) bool) (k int, v interface{}) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// InterfacesIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func InterfacesIncludes(i []interface{}, valueToFind int64, fromIndex ...int) bool { + return InterfacesIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// InterfacesIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func InterfacesIndexOf(i []interface{}, searchElement int64, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// InterfacesLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func InterfacesLastIndexOf(i []interface{}, searchElement int64, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// InterfacesMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func InterfacesMap(i []interface{}, fn func(i []interface{}, k int, v interface{}) int64) []int64 { + ret := make([]int64, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// InterfacesPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func InterfacesPop(i *[]interface{}) (interface{}, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// InterfacesPush adds one or more elements to the end of an slice and returns the new length of the slice. +func InterfacesPush(i *[]interface{}, element ...interface{}) int { + *i = append(*i, element...) + return len(*i) +} + +// InterfacesPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func InterfacesPushDistinct(i []interface{}, element ...interface{}) []interface{} { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// InterfacesReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func InterfacesReduce( + i []interface{}, + fn func(i []interface{}, k int, v, accumulator interface{}) interface{}, initialValue ...interface{}, +) interface{} { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// InterfacesReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func InterfacesReduceRight( + i []interface{}, + fn func(i []interface{}, k int, v, accumulator interface{}) interface{}, initialValue ...interface{}, +) interface{} { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// InterfacesReverse reverses an slice in place. +func InterfacesReverse(i []interface{}) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// InterfacesShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func InterfacesShift(i *[]interface{}) (interface{}, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// InterfacesSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func InterfacesSlice(i []interface{}, begin int, end ...int) []interface{} { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []interface{}{} + } + return InterfacesCopy(i[fixedStart:fixedEnd]) +} + +// InterfacesSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func InterfacesSome(i []interface{}, fn func(i []interface{}, k int, v interface{}) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// InterfacesSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func InterfacesSplice(i *[]interface{}, start, deleteCount int, items ...interface{}) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := InterfacesCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// InterfacesUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func InterfacesUnshift(i *[]interface{}, element ...interface{}) int { + *i = append(element, *i...) + return len(*i) +} + +// InterfacesUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func InterfacesUnshiftDistinct(i *[]interface{}, element ...interface{}) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[interface{}]bool, len(element)) + r := make([]interface{}, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// InterfacesRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func InterfacesRemoveFirst(p *[]interface{}, elements ...interface{}) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// InterfacesRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func InterfacesRemoveEvery(p *[]interface{}, elements ...interface{}) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// InterfacesConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func InterfacesConcat(i ...[]interface{}) []interface{} { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]interface{}, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// InterfacesIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func InterfacesIntersect(i ...[]interface{}) (intersectCount map[interface{}]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[interface{}]int, len(i)) + for k, v := range i { + counts[k] = interfacesDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// InterfacesDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func InterfacesDistinct(i *[]interface{}, changeSlice bool) (distinctCount map[interface{}]int) { + if !changeSlice { + return interfacesDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = interfacesDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func interfacesDistinct(src []interface{}, dst *[]interface{}) map[interface{}]int { + m := make(map[interface{}]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} diff --git a/vendor/github.com/henrylee2cn/ameda/ints.go b/vendor/github.com/henrylee2cn/ameda/ints.go new file mode 100644 index 0000000..0bc8cb0 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/ints.go @@ -0,0 +1,682 @@ +package ameda + +// OneInt try to return the first element, otherwise return zero value. +func OneInt(i []int) int { + if len(i) > 0 { + return i[0] + } + return 0 +} + +// IntsCopy creates a copy of the int slice. +func IntsCopy(i []int) []int { + b := make([]int, len(i)) + copy(b, i) + return b +} + +// IntsToInterfaces converts int slice to interface slice. +func IntsToInterfaces(i []int) []interface{} { + r := make([]interface{}, len(i)) + for k, v := range i { + r[k] = IntToInterface(v) + } + return r +} + +// IntsToStrings converts int slice to string slice. +func IntsToStrings(i []int) []string { + r := make([]string, len(i)) + for k, v := range i { + r[k] = IntToString(v) + } + return r +} + +// IntsToBools converts int slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func IntsToBools(i []int) []bool { + r := make([]bool, len(i)) + for k, v := range i { + r[k] = IntToBool(v) + } + return r +} + +// IntsToFloat32s converts int slice to float32 slice. +func IntsToFloat32s(i []int) []float32 { + r := make([]float32, len(i)) + for k, v := range i { + r[k] = IntToFloat32(v) + } + return r +} + +// IntsToFloat64s converts int slice to float64 slice. +func IntsToFloat64s(i []int) []float64 { + r := make([]float64, len(i)) + for k, v := range i { + r[k] = IntToFloat64(v) + } + return r +} + +// IntsToInt8s converts int slice to int8 slice. +func IntsToInt8s(i []int) ([]int8, error) { + var err error + r := make([]int8, len(i)) + for k, v := range i { + r[k], err = IntToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToInt16s converts int slice to int16 slice. +func IntsToInt16s(i []int) ([]int16, error) { + var err error + r := make([]int16, len(i)) + for k, v := range i { + r[k], err = IntToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToInt32s converts int slice to int32 slice. +func IntsToInt32s(i []int) ([]int32, error) { + var err error + r := make([]int32, len(i)) + for k, v := range i { + r[k], err = IntToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToInt64s converts int slice to int64 slice. +func IntsToInt64s(i []int) []int64 { + r := make([]int64, len(i)) + for k, v := range i { + r[k] = IntToInt64(v) + } + return r +} + +// IntsToUints converts int slice to uint slice. +func IntsToUints(i []int) ([]uint, error) { + var err error + r := make([]uint, len(i)) + for k, v := range i { + r[k], err = IntToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToUint8s converts int slice to uint8 slice. +func IntsToUint8s(i []int) ([]uint8, error) { + var err error + r := make([]uint8, len(i)) + for k, v := range i { + r[k], err = IntToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToUint16s converts int slice to uint16 slice. +func IntsToUint16s(i []int) ([]uint16, error) { + var err error + r := make([]uint16, len(i)) + for k, v := range i { + r[k], err = IntToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToUint32s converts int slice to uint32 slice. +func IntsToUint32s(i []int) ([]uint32, error) { + var err error + r := make([]uint32, len(i)) + for k, v := range i { + r[k], err = IntToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsToUint64s converts int slice to uint64 slice. +func IntsToUint64s(i []int) ([]uint64, error) { + var err error + r := make([]uint64, len(i)) + for k, v := range i { + r[k], err = IntToUint64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// IntsCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func IntsCopyWithin(i []int, target, start int, end ...int) { + target = fixIndex(len(i), target, true) + if target == len(i) { + return + } + sub := IntsSlice(i, start, end...) + for k, v := range sub { + i[target+k] = v + } +} + +// IntsEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func IntsEvery(i []int, fn func(i []int, k int, v int) bool) bool { + for k, v := range i { + if !fn(i, k, v) { + return false + } + } + return true +} + +// IntsFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func IntsFill(i []int, value int, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + i[k] = value + } +} + +// IntsFilter creates a new slice with all elements that pass the test implemented by the provided function. +func IntsFilter(i []int, fn func(i []int, k int, v int) bool) []int { + ret := make([]int, 0) + for k, v := range i { + if fn(i, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// IntsFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func IntsFind(i []int, fn func(i []int, k int, v int) bool) (k int, v int) { + for k, v := range i { + if fn(i, k, v) { + return k, v + } + } + return -1, 0 +} + +// IntsIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func IntsIncludes(i []int, valueToFind int, fromIndex ...int) bool { + return IntsIndexOf(i, valueToFind, fromIndex...) > -1 +} + +// IntsIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func IntsIndexOf(i []int, searchElement int, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k, v := range i[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// IntsLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func IntsLastIndexOf(i []int, searchElement int, fromIndex ...int) int { + idx := getFromIndex(len(i), fromIndex...) + for k := len(i) - 1; k >= idx; k-- { + if searchElement == i[k] { + return k + } + } + return -1 +} + +// IntsMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func IntsMap(i []int, fn func(i []int, k int, v int) int) []int { + ret := make([]int, len(i)) + for k, v := range i { + ret[k] = fn(i, k, v) + } + return ret +} + +// IntsPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func IntsPop(i *[]int) (int, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *i = a[:len(a):len(a)] + return last, true +} + +// IntsPush adds one or more elements to the end of an slice and returns the new length of the slice. +func IntsPush(i *[]int, element ...int) int { + *i = append(*i, element...) + return len(*i) +} + +// IntsPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func IntsPushDistinct(i []int, element ...int) []int { +L: + for _, v := range element { + for _, vv := range i { + if vv == v { + continue L + } + } + i = append(i, v) + } + return i +} + +// IntsReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func IntsReduce(i []int, fn func(i []int, k int, v, accumulator int) int, initialValue ...int) int { + if len(i) == 0 { + return 0 + } + start := 0 + acc := i[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(i); k++ { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// IntsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func IntsReduceRight(i []int, fn func(i []int, k int, v, accumulator int) int, initialValue ...int) int { + if len(i) == 0 { + return 0 + } + end := len(i) - 1 + acc := i[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(i, k, i[k], acc) + } + return acc +} + +// IntsReverse reverses an slice in place. +func IntsReverse(i []int) { + first := 0 + last := len(i) - 1 + for first < last { + i[first], i[last] = i[last], i[first] + first++ + last-- + } +} + +// IntsShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func IntsShift(i *[]int) (int, bool) { + a := *i + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *i = a[:len(a):len(a)] + return first, true +} + +// IntsSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func IntsSlice(i []int, begin int, end ...int) []int { + fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) + if !ok { + return []int{} + } + return IntsCopy(i[fixedStart:fixedEnd]) +} + +// IntsSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func IntsSome(i []int, fn func(i []int, k int, v int) bool) bool { + for k, v := range i { + if fn(i, k, v) { + return true + } + } + return false +} + +// IntsSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func IntsSplice(i *[]int, start, deleteCount int, items ...int) { + a := *i + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := IntsCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *i = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *i = a[:len(a):len(a)] +} + +// IntsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func IntsUnshift(i *[]int, element ...int) int { + *i = append(element, *i...) + return len(*i) +} + +// IntsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func IntsUnshiftDistinct(i *[]int, element ...int) int { + a := *i + if len(element) == 0 { + return len(a) + } + m := make(map[int]bool, len(element)) + r := make([]int, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *i = r[:len(r):len(r)] + return len(r) +} + +// IntsRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func IntsRemoveFirst(p *[]int, elements ...int) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// IntsRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func IntsRemoveEvery(p *[]int, elements ...int) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// IntsConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func IntsConcat(i ...[]int) []int { + var totalLen int + for _, v := range i { + totalLen += len(v) + } + ret := make([]int, totalLen) + dst := ret + for _, v := range i { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// IntsIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func IntsIntersect(i ...[]int) (intersectCount map[int]int) { + if len(i) == 0 { + return nil + } + for _, v := range i { + if len(v) == 0 { + return nil + } + } + counts := make([]map[int]int, len(i)) + for k, v := range i { + counts[k] = intsDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// IntsDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func IntsDistinct(i *[]int, changeSlice bool) (distinctCount map[int]int) { + if !changeSlice { + return intsDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = intsDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func intsDistinct(src []int, dst *[]int) map[int]int { + m := make(map[int]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// IntSetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func IntSetUnion(set1, set2 []int, others ...[]int) []int { + m := make(map[int]struct{}, len(set1)+len(set2)) + r := make([]int, 0, len(m)) + for _, set := range append([][]int{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// IntSetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func IntSetIntersect(set1, set2 []int, others ...[]int) []int { + sets := append([][]int{set2}, others...) + setsCount := make([]map[int]int, len(sets)) + for k, v := range sets { + setsCount[k] = intsDistinct(v, nil) + } + m := make(map[int]struct{}, len(set1)) + r := make([]int, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// IntSetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func IntSetDifference(set1, set2 []int, others ...[]int) []int { + m := make(map[int]struct{}, len(set1)) + r := make([]int, 0, len(set1)) + sets := append([][]int{set2}, others...) + for _, v := range sets { + inter := IntSetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/itoa62.go b/vendor/github.com/henrylee2cn/ameda/itoa62.go new file mode 100644 index 0000000..6aaa07a --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/itoa62.go @@ -0,0 +1,210 @@ +package ameda + +import "math/bits" + +// FormatUint returns the string representation of i in the given base, +// for 2 <= base <= 62. +// NOTE: +// Compatible with standard package strconv. +func FormatUint(i uint64, base int) string { + if fastSmalls && i < nSmalls && base == 10 { + return small(int(i)) + } + _, s := formatBits(nil, i, base, false, false) + return s +} + +// FormatInt returns the string representation of i in the given base, +// for 2 <= base <= 62. +// NOTE: +// Compatible with standard package strconv. +func FormatInt(i int64, base int) string { + if fastSmalls && 0 <= i && i < nSmalls && base == 10 { + return small(int(i)) + } + _, s := formatBits(nil, uint64(i), base, i < 0, false) + return s +} + +// Itoa is equivalent to FormatInt(int64(i), 10). +// NOTE: +// Compatible with standard package strconv. +func Itoa(i int) string { + return FormatInt(int64(i), 10) +} + +// AppendInt appends the string form of the integer i, +// as generated by FormatInt, to dst and returns the extended buffer. +// NOTE: +// Compatible with standard package strconv. +func AppendInt(dst []byte, i int64, base int) []byte { + if fastSmalls && 0 <= i && i < nSmalls && base == 10 { + return append(dst, small(int(i))...) + } + dst, _ = formatBits(dst, uint64(i), base, i < 0, true) + return dst +} + +// AppendUint appends the string form of the unsigned integer i, +// as generated by FormatUint, to dst and returns the extended buffer. +// NOTE: +// Compatible with standard package strconv. +func AppendUint(dst []byte, i uint64, base int) []byte { + if fastSmalls && i < nSmalls && base == 10 { + return append(dst, small(int(i))...) + } + dst, _ = formatBits(dst, i, base, false, true) + return dst +} + +const ( + digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +) + +const ( + fastSmalls = true // enable fast path for small integers + nSmalls = 100 + smallsString = "00010203040506070809" + + "10111213141516171819" + + "20212223242526272829" + + "30313233343536373839" + + "40414243444546474849" + + "50515253545556575859" + + "60616263646566676869" + + "70717273747576777879" + + "80818283848586878889" + + "90919293949596979899" +) + +// small returns the string for an i with 0 <= i < nSmalls. +func small(i int) string { + if i < 10 { + return digits[i : i+1] + } + return smallsString[i*2 : i*2+2] +} + +// formatBits computes the string representation of u in the given base. +// If neg is set, u is treated as negative int64 value. If append_ is +// set, the string is appended to dst and the resulting byte slice is +// returned as the first result value; otherwise the string is returned +// as the second result value. +// +func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) { + if base < 2 || base > len(digits) { + panic("ameda(strconv): illegal AppendInt/FormatInt base") + } + // 2 <= base && base <= len(digits) + + var a [64 + 1]byte // +1 for sign of 64bit value in base 2 + i := len(a) + + if neg { + u = -u + } + + // convert bits + // We use uint values where we can because those will + // fit into a single register even on a 32bit machine. + if base == 10 { + // common case: use constants for / because + // the compiler can optimize it into a multiply+shift + + if Host32bit { + // convert the lower digits using 32bit operations + for u >= 1e9 { + // Avoid using r = a%b in addition to q = a/b + // since 64bit division and modulo operations + // are calculated by runtime functions on 32bit machines. + q := u / 1e9 + us := uint(u - q*1e9) // u % 1e9 fits into a uint + for j := 4; j > 0; j-- { + is := us % 100 * 2 + us /= 100 + i -= 2 + a[i+1] = smallsString[is+1] + a[i+0] = smallsString[is+0] + } + + // us < 10, since it contains the last digit + // from the initial 9-digit us. + i-- + a[i] = smallsString[us*2+1] + + u = q + } + // u < 1e9 + } + + // u guaranteed to fit into a uint + us := uint(u) + for us >= 100 { + is := us % 100 * 2 + us /= 100 + i -= 2 + a[i+1] = smallsString[is+1] + a[i+0] = smallsString[is+0] + } + + // us < 100 + is := us * 2 + i-- + a[i] = smallsString[is+1] + if us >= 10 { + i-- + a[i] = smallsString[is] + } + + } else if isPowerOfTwo(base) { + // Use shifts and masks instead of / and %. + // Base is a power of 2 and 2 <= base <= len(digits) where len(digits) is 62. + // The largest power of 2 below or equal to 62 is 32, which is 1 << 5; + // i.e., the largest possible shift count is 5. By &-ind that value with + // the constant 7 we tell the compiler that the shift count is always + // less than 8 which is smaller than any register width. This allows + // the compiler to generate better code for the shift operation. + shift := uint(bits.TrailingZeros(uint(base))) & 7 + b := uint64(base) + m := uint(base) - 1 // == 1<= b { + i-- + a[i] = digits[uint(u)&m] + u >>= shift + } + // u < base + i-- + a[i] = digits[uint(u)] + } else { + // general case + b := uint64(base) + for u >= b { + i-- + // Avoid using r = a%b in addition to q = a/b + // since 64bit division and modulo operations + // are calculated by runtime functions on 32bit machines. + q := u / b + a[i] = digits[uint(u-q*b)] + u = q + } + // u < base + i-- + a[i] = digits[uint(u)] + } + + // add sign, if any + if neg { + i-- + a[i] = '-' + } + + if append_ { + d = append(dst, a[i:]...) + return + } + s = string(a[i:]) + return +} + +func isPowerOfTwo(x int) bool { + return x&(x-1) == 0 +} diff --git a/vendor/github.com/henrylee2cn/ameda/itoa_x.go b/vendor/github.com/henrylee2cn/ameda/itoa_x.go new file mode 100644 index 0000000..68aee00 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/itoa_x.go @@ -0,0 +1,21 @@ +package ameda + +// FormatUintByDict convert num into corresponding string according to dict. +func FormatUintByDict(dict []byte, num uint64) string { + var base = uint64(len(dict)) + if base == 0 { + return "" + } + var str []byte + for { + tmp := make([]byte, len(str)+1) + tmp[0] = dict[num%base] + copy(tmp[1:], str) + str = tmp + num = num / base + if num == 0 { + break + } + } + return string(str) +} diff --git a/vendor/github.com/henrylee2cn/ameda/string.go b/vendor/github.com/henrylee2cn/ameda/string.go new file mode 100644 index 0000000..f169b67 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/string.go @@ -0,0 +1,242 @@ +package ameda + +import ( + "strconv" +) + +// StringToInterface converts string to interface. +func StringToInterface(v string) interface{} { + return v +} + +// StringToInterfacePtr converts string to *interface. +func StringToInterfacePtr(v string) *interface{} { + r := StringToInterface(v) + return &r +} + +// StringToStringPtr converts string to *string. +func StringToStringPtr(v string) *string { + return &v +} + +// StringToBool converts string to bool. +func StringToBool(v string, emptyAsFalse ...bool) (bool, error) { + r, err := strconv.ParseBool(v) + if err != nil { + if !isEmptyAsZero(emptyAsFalse) { + return false, err + } + } + return r, nil +} + +// StringToBoolPtr converts string to *bool. +func StringToBoolPtr(v string, emptyAsFalse ...bool) (*bool, error) { + r, err := StringToBool(v, emptyAsFalse...) + return &r, err +} + +// StringToFloat32 converts string to float32. +func StringToFloat32(v string, emptyAsZero ...bool) (float32, error) { + i, err := strconv.ParseFloat(v, 32) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return float32(i), nil +} + +// StringToFloat32Ptr converts string to *float32. +func StringToFloat32Ptr(v string, emptyAsZero ...bool) (*float32, error) { + r, err := StringToFloat32(v, emptyAsZero...) + return &r, err +} + +// StringToFloat64 converts string to float64. +func StringToFloat64(v string, emptyAsZero ...bool) (float64, error) { + i, err := strconv.ParseFloat(v, 64) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return i, nil +} + +// StringToFloat64Ptr converts string to *float64. +func StringToFloat64Ptr(v string, emptyAsZero ...bool) (*float64, error) { + r, err := StringToFloat64(v, emptyAsZero...) + return &r, err +} + +// StringToInt converts string to int. +func StringToInt(v string, emptyAsZero ...bool) (int, error) { + i, err := strconv.Atoi(v) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return i, nil +} + +// StringToIntPtr converts string to *int. +func StringToIntPtr(v string, emptyAsZero ...bool) (*int, error) { + r, err := StringToInt(v, emptyAsZero...) + return &r, err +} + +// StringToInt8 converts string to int8. +func StringToInt8(v string, emptyAsZero ...bool) (int8, error) { + i, err := strconv.ParseInt(v, 10, 8) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return int8(i), nil +} + +// StringToInt8Ptr converts string to *int8. +func StringToInt8Ptr(v string, emptyAsZero ...bool) (*int8, error) { + r, err := StringToInt8(v, emptyAsZero...) + return &r, err +} + +// StringToInt16 converts string to int16. +func StringToInt16(v string, emptyAsZero ...bool) (int16, error) { + i, err := strconv.ParseInt(v, 10, 16) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return int16(i), nil +} + +// StringToInt16Ptr converts string to *int16. +func StringToInt16Ptr(v string, emptyAsZero ...bool) (*int16, error) { + r, err := StringToInt16(v, emptyAsZero...) + return &r, err +} + +// StringToInt32 converts string to int32. +func StringToInt32(v string, emptyAsZero ...bool) (int32, error) { + i, err := strconv.ParseInt(v, 10, 32) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return int32(i), nil +} + +// StringToInt32Ptr converts string to *int32. +func StringToInt32Ptr(v string, emptyAsZero ...bool) (*int32, error) { + r, err := StringToInt32(v, emptyAsZero...) + return &r, err +} + +// StringToInt64 converts string to int64. +func StringToInt64(v string, emptyAsZero ...bool) (int64, error) { + i, err := strconv.ParseInt(v, 10, 64) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return i, nil +} + +// StringToInt64Ptr converts string to *int64. +func StringToInt64Ptr(v string, emptyAsZero ...bool) (*int64, error) { + r, err := StringToInt64(v, emptyAsZero...) + return &r, err +} + +// StringToUint converts string to uint. +func StringToUint(v string, emptyAsZero ...bool) (uint, error) { + u, err := strconv.ParseUint(v, 10, strconv.IntSize) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return uint(u), nil +} + +// StringToUintPtr converts string to *uint. +func StringToUintPtr(v string, emptyAsZero ...bool) (*uint, error) { + r, err := StringToUint(v, emptyAsZero...) + return &r, err +} + +// StringToUint8 converts string to uint8. +func StringToUint8(v string, emptyAsZero ...bool) (uint8, error) { + u, err := strconv.ParseUint(v, 10, 8) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return uint8(u), nil +} + +// StringToUint8Ptr converts string to *uint8. +func StringToUint8Ptr(v string, emptyAsZero ...bool) (*uint8, error) { + r, err := StringToUint8(v, emptyAsZero...) + return &r, err +} + +// StringToUint16 converts string to uint16. +func StringToUint16(v string, emptyAsZero ...bool) (uint16, error) { + u, err := strconv.ParseUint(v, 10, 16) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return uint16(u), nil +} + +// StringToUint16Ptr converts string to *uint16. +func StringToUint16Ptr(v string, emptyAsZero ...bool) (*uint16, error) { + r, err := StringToUint16(v, emptyAsZero...) + return &r, err +} + +// StringToUint32 converts string to uint32. +func StringToUint32(v string, emptyAsZero ...bool) (uint32, error) { + u, err := strconv.ParseUint(v, 10, 32) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return uint32(u), nil +} + +// StringToUint32Ptr converts string to *uint32. +func StringToUint32Ptr(v string, emptyAsZero ...bool) (*uint32, error) { + r, err := StringToUint32(v, emptyAsZero...) + return &r, err +} + +// StringToUint64 converts string to uint64. +func StringToUint64(v string, emptyAsZero ...bool) (uint64, error) { + u, err := strconv.ParseUint(v, 10, 64) + if err != nil { + if !isEmptyAsZero(emptyAsZero) { + return 0, err + } + } + return u, nil +} + +// StringToUint64Ptr converts string to *uint64. +func StringToUint64Ptr(v string, emptyAsZero ...bool) (*uint64, error) { + r, err := StringToUint64(v, emptyAsZero...) + return &r, err +} diff --git a/vendor/github.com/henrylee2cn/ameda/strings.go b/vendor/github.com/henrylee2cn/ameda/strings.go new file mode 100644 index 0000000..2643b57 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/strings.go @@ -0,0 +1,710 @@ +package ameda + +import ( + "strings" +) + +// OneString try to return the first element, otherwise return zero value. +func OneString(s []string) string { + if len(s) > 0 { + return s[0] + } + return "" +} + +// StringsCopy creates a copy of the string slice. +func StringsCopy(s []string) []string { + b := make([]string, len(s)) + copy(b, s) + return b +} + +// StringsToInterfaces converts string slice to interface slice. +func StringsToInterfaces(s []string) []interface{} { + r := make([]interface{}, len(s)) + for k, v := range s { + r[k] = StringToInterface(v) + } + return r +} + +// StringsToBools converts string slice to bool slice. +func StringsToBools(s []string, emptyAsZero ...bool) ([]bool, error) { + var err error + r := make([]bool, len(s)) + for k, v := range s { + r[k], err = StringToBool(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToFloat32s converts string slice to float32 slice. +func StringsToFloat32s(s []string, emptyAsZero ...bool) ([]float32, error) { + var err error + r := make([]float32, len(s)) + for k, v := range s { + r[k], err = StringToFloat32(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToFloat64s converts string slice to float64 slice. +func StringsToFloat64s(s []string, emptyAsZero ...bool) ([]float64, error) { + var err error + r := make([]float64, len(s)) + for k, v := range s { + r[k], err = StringToFloat64(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToInts converts string slice to int slice. +func StringsToInts(s []string, emptyAsZero ...bool) ([]int, error) { + var err error + r := make([]int, len(s)) + for k, v := range s { + r[k], err = StringToInt(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToInt8s converts string slice to int8 slice. +func StringsToInt8s(s []string, emptyAsZero ...bool) ([]int8, error) { + var err error + r := make([]int8, len(s)) + for k, v := range s { + r[k], err = StringToInt8(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToInt16s converts string slice to int16 slice. +func StringsToInt16s(s []string, emptyAsZero ...bool) ([]int16, error) { + var err error + r := make([]int16, len(s)) + for k, v := range s { + r[k], err = StringToInt16(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToInt32s converts string slice to int32 slice. +func StringsToInt32s(s []string, emptyAsZero ...bool) ([]int32, error) { + var err error + r := make([]int32, len(s)) + for k, v := range s { + r[k], err = StringToInt32(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToInt64s converts string slice to int64 slice. +func StringsToInt64s(s []string, emptyAsZero ...bool) ([]int64, error) { + var err error + r := make([]int64, len(s)) + for k, v := range s { + r[k], err = StringToInt64(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToUints converts string slice to uint slice. +func StringsToUints(s []string, emptyAsZero ...bool) ([]uint, error) { + var err error + r := make([]uint, len(s)) + for k, v := range s { + r[k], err = StringToUint(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToUint8s converts string slice to uint8 slice. +func StringsToUint8s(s []string, emptyAsZero ...bool) ([]uint8, error) { + var err error + r := make([]uint8, len(s)) + for k, v := range s { + r[k], err = StringToUint8(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToUint16s converts string slice to uint16 slice. +func StringsToUint16s(s []string, emptyAsZero ...bool) ([]uint16, error) { + var err error + r := make([]uint16, len(s)) + for k, v := range s { + r[k], err = StringToUint16(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToUint32s converts string slice to uint32 slice. +func StringsToUint32s(s []string, emptyAsZero ...bool) ([]uint32, error) { + var err error + r := make([]uint32, len(s)) + for k, v := range s { + r[k], err = StringToUint32(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsToUint64s converts string slice to uint64 slice. +func StringsToUint64s(s []string, emptyAsZero ...bool) ([]uint64, error) { + var err error + r := make([]uint64, len(s)) + for k, v := range s { + r[k], err = StringToUint64(v, emptyAsZero...) + if err != nil { + return r, err + } + } + return r, nil +} + +// StringsCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func StringsCopyWithin(s []string, target, start int, end ...int) { + target = fixIndex(len(s), target, true) + if target == len(s) { + return + } + sub := StringsSlice(s, start, end...) + for i, v := range sub { + s[target+i] = v + } +} + +// StringsEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func StringsEvery(s []string, fn func(s []string, k int, v string) bool) bool { + for k, v := range s { + if !fn(s, k, v) { + return false + } + } + return true +} + +// StringsFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func StringsFill(s []string, value string, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(s), start, end...) + if !ok { + return + } + for i := fixedStart; i < fixedEnd; i++ { + s[i] = value + } +} + +// StringsFilter creates a new slice with all elements that pass the test implemented by the provided function. +func StringsFilter(s []string, fn func(s []string, k int, v string) bool) []string { + ret := make([]string, 0) + for k, v := range s { + if fn(s, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// StringsFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func StringsFind(s []string, fn func(s []string, k int, v string) bool) (k int, v string) { + for k, v := range s { + if fn(s, k, v) { + return k, v + } + } + return -1, "" +} + +// StringsIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func StringsIncludes(s []string, valueToFind string, fromIndex ...int) bool { + return StringsIndexOf(s, valueToFind, fromIndex...) > -1 +} + +// StringsIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func StringsIndexOf(s []string, searchElement string, fromIndex ...int) int { + idx := getFromIndex(len(s), fromIndex...) + for k, v := range s[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// StringsJoin concatenates the elements of s to create a single string. The separator string +// sep is placed between elements in the resulting string. +func StringsJoin(s []string, sep string) string { + return strings.Join(s, sep) +} + +// StringsLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func StringsLastIndexOf(s []string, searchElement string, fromIndex ...int) int { + idx := getFromIndex(len(s), fromIndex...) + for i := len(s) - 1; i >= idx; i-- { + if searchElement == s[i] { + return i + } + } + return -1 +} + +// StringsMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func StringsMap(s []string, fn func(s []string, k int, v string) string) []string { + ret := make([]string, len(s)) + for k, v := range s { + ret[k] = fn(s, k, v) + } + return ret +} + +// StringsPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func StringsPop(s *[]string) (string, bool) { + a := *s + if len(a) == 0 { + return "", false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *s = a[:len(a):len(a)] + return last, true +} + +// StringsPush adds one or more elements to the end of an slice and returns the new length of the slice. +func StringsPush(s *[]string, element ...string) int { + *s = append(*s, element...) + return len(*s) +} + +// StringsPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func StringsPushDistinct(s []string, element ...string) []string { +L: + for _, v := range element { + for _, vv := range s { + if vv == v { + continue L + } + } + s = append(s, v) + } + return s +} + +// StringsReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func StringsReduce(s []string, fn func(s []string, k int, v, accumulator string) string, initialValue ...string) string { + if len(s) == 0 { + return "" + } + start := 0 + acc := s[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for i := start; i < len(s); i++ { + acc = fn(s, i, s[i], acc) + } + return acc +} + +// StringsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func StringsReduceRight(s []string, fn func(s []string, k int, v, accumulator string) string, initialValue ...string) string { + if len(s) == 0 { + return "" + } + end := len(s) - 1 + acc := s[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for i := end; i >= 0; i-- { + acc = fn(s, i, s[i], acc) + } + return acc +} + +// StringsReverse reverses an slice in place. +func StringsReverse(s []string) { + first := 0 + last := len(s) - 1 + for first < last { + s[first], s[last] = s[last], s[first] + first++ + last-- + } +} + +// StringsShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func StringsShift(s *[]string) (string, bool) { + a := *s + if len(a) == 0 { + return "", false + } + first := a[0] + a = a[1:] + *s = a[:len(a):len(a)] + return first, true +} + +// StringsSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func StringsSlice(s []string, begin int, end ...int) []string { + fixedStart, fixedEnd, ok := fixRange(len(s), begin, end...) + if !ok { + return []string{} + } + return StringsCopy(s[fixedStart:fixedEnd]) +} + +// StringsSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func StringsSome(s []string, fn func(s []string, k int, v string) bool) bool { + for k, v := range s { + if fn(s, k, v) { + return true + } + } + return false +} + +// StringsSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func StringsSplice(s *[]string, start, deleteCount int, items ...string) { + a := *s + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for i := 0; i < len(items); i++ { + if deleteCount > 0 { + // replace + a[start] = items[i] + deleteCount-- + start++ + } else { + // insert + lastSlice := StringsCopy(a[start:]) + items = items[i:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *s = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *s = a[:len(a):len(a)] +} + +// StringsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func StringsUnshift(s *[]string, element ...string) int { + *s = append(element, *s...) + return len(*s) +} + +// StringsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func StringsUnshiftDistinct(s *[]string, element ...string) int { + a := *s + if len(element) == 0 { + return len(a) + } + m := make(map[string]bool, len(element)) + r := make([]string, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *s = r[:len(r):len(r)] + return len(r) +} + +// StringsRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func StringsRemoveFirst(p *[]string, elements ...string) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// StringsRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func StringsRemoveEvery(p *[]string, elements ...string) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// StringsConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func StringsConcat(s ...[]string) []string { + var totalLen int + for _, v := range s { + totalLen += len(v) + } + ret := make([]string, totalLen) + dst := ret + for _, v := range s { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// StringsIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func StringsIntersect(s ...[]string) (intersectCount map[string]int) { + if len(s) == 0 { + return nil + } + for _, v := range s { + if len(v) == 0 { + return nil + } + } + counts := make([]map[string]int, len(s)) + for k, v := range s { + counts[k] = stringsDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// StringsDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func StringsDistinct(s *[]string, changeSlice bool) (distinctCount map[string]int) { + if !changeSlice { + return stringsDistinct(*s, nil) + } + a := (*s)[:0] + distinctCount = stringsDistinct(*s, &a) + n := len(distinctCount) + *s = a[:n:n] + return distinctCount +} + +func stringsDistinct(src []string, dst *[]string) map[string]int { + m := make(map[string]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// StringSetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func StringSetUnion(set1, set2 []string, others ...[]string) []string { + m := make(map[string]struct{}, len(set1)+len(set2)) + r := make([]string, 0, len(m)) + for _, set := range append([][]string{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// StringSetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func StringSetIntersect(set1, set2 []string, others ...[]string) []string { + sets := append([][]string{set2}, others...) + setsCount := make([]map[string]int, len(sets)) + for k, v := range sets { + setsCount[k] = stringsDistinct(v, nil) + } + m := make(map[string]struct{}, len(set1)) + r := make([]string, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// StringSetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func StringSetDifference(set1, set2 []string, others ...[]string) []string { + m := make(map[string]struct{}, len(set1)) + r := make([]string, 0, len(set1)) + sets := append([][]string{set2}, others...) + for _, v := range sets { + inter := StringSetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/typconv.go b/vendor/github.com/henrylee2cn/ameda/typconv.go new file mode 100644 index 0000000..7f972b0 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/typconv.go @@ -0,0 +1,138 @@ +package ameda + +import ( + "reflect" + "unsafe" +) + +// UnsafeBytesToString convert []byte type to string type. +func UnsafeBytesToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +// UnsafeStringToBytes convert string type to []byte type. +// NOTE: +// panic if modify the member value of the []byte. +func UnsafeStringToBytes(s string) []byte { + sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) + bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len} + return *(*[]byte)(unsafe.Pointer(&bh)) +} + +// IndirectValue gets the indirect value. +func IndirectValue(v reflect.Value) reflect.Value { + if !v.IsValid() { + return v + } + if v.Kind() != reflect.Ptr { + // Avoid creating a reflect.Value if it's not a pointer. + return v + } + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v +} + +// DereferenceType dereference, get the underlying non-pointer type. +func DereferenceType(t reflect.Type) reflect.Type { + for t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + +// DereferenceValue dereference and unpack interface, +// get the underlying non-pointer and non-interface value. +func DereferenceValue(v reflect.Value) reflect.Value { + for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { + v = v.Elem() + } + return v +} + +// DereferencePtrValue returns the underlying non-pointer type value. +func DereferencePtrValue(v reflect.Value) reflect.Value { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + return v +} + +// DereferenceInterfaceValue returns the value of the underlying type that implements the interface v. +func DereferenceInterfaceValue(v reflect.Value) reflect.Value { + for v.Kind() == reflect.Interface { + v = v.Elem() + } + return v +} + +// DereferenceImplementType returns the underlying type of the value that implements the interface v. +func DereferenceImplementType(v reflect.Value) reflect.Type { + return DereferenceType(DereferenceInterfaceValue(v).Type()) +} + +// DereferenceSlice convert []*T to []T. +func DereferenceSlice(v reflect.Value) reflect.Value { + m := v.Len() - 1 + if m < 0 { + return reflect.New(reflect.SliceOf(DereferenceType(v.Type().Elem()))).Elem() + } + s := make([]reflect.Value, m+1) + for ; m >= 0; m-- { + s[m] = DereferenceValue(v.Index(m)) + } + v = reflect.New(reflect.SliceOf(s[0].Type())).Elem() + v = reflect.Append(v, s...) + return v +} + +// ReferenceSlice convert []T to []*T, the ptrDepth is the count of '*'. +func ReferenceSlice(v reflect.Value, ptrDepth int) reflect.Value { + if ptrDepth <= 0 { + return v + } + m := v.Len() - 1 + if m < 0 { + return reflect.New(reflect.SliceOf(ReferenceType(v.Type().Elem(), ptrDepth))).Elem() + } + s := make([]reflect.Value, m+1) + for ; m >= 0; m-- { + s[m] = ReferenceValue(v.Index(m), ptrDepth) + } + v = reflect.New(reflect.SliceOf(s[0].Type())).Elem() + v = reflect.Append(v, s...) + return v +} + +// ReferenceType convert T to *T, the ptrDepth is the count of '*'. +func ReferenceType(t reflect.Type, ptrDepth int) reflect.Type { + switch { + case ptrDepth > 0: + for ; ptrDepth > 0; ptrDepth-- { + t = reflect.PtrTo(t) + } + case ptrDepth < 0: + for ; ptrDepth < 0 && t.Kind() == reflect.Ptr; ptrDepth++ { + t = t.Elem() + } + } + return t +} + +// ReferenceValue convert T to *T, the ptrDepth is the count of '*'. +func ReferenceValue(v reflect.Value, ptrDepth int) reflect.Value { + switch { + case ptrDepth > 0: + for ; ptrDepth > 0; ptrDepth-- { + vv := reflect.New(v.Type()) + vv.Elem().Set(v) + v = vv + } + case ptrDepth < 0: + for ; ptrDepth < 0 && v.Kind() == reflect.Ptr; ptrDepth++ { + v = v.Elem() + } + } + return v +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint.go b/vendor/github.com/henrylee2cn/ameda/uint.go new file mode 100644 index 0000000..7917ded --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint.go @@ -0,0 +1,203 @@ +package ameda + +import ( + "math" + "strconv" +) + +// MaxUint returns max uint number for current os. +func MaxUint() uint { + if Host32bit { + return math.MaxUint32 + } + return math.MaxUint64 +} + +// UintToInterface converts uint to interface. +func UintToInterface(v uint) interface{} { + return v +} + +// UintToInterfacePtr converts uint to *interface. +func UintToInterfacePtr(v uint) *interface{} { + r := UintToInterface(v) + return &r +} + +// UintToString converts uint to string. +func UintToString(v uint) string { + return strconv.FormatUint(uint64(v), 10) +} + +// UintToStringPtr converts uint to *string. +func UintToStringPtr(v uint) *string { + r := UintToString(v) + return &r +} + +// UintToBool converts uint to bool. +func UintToBool(v uint) bool { + return v != 0 +} + +// UintToBoolPtr converts uint to *bool. +func UintToBoolPtr(v uint) *bool { + r := UintToBool(v) + return &r +} + +// UintToFloat32 converts uint to float32. +func UintToFloat32(v uint) float32 { + return float32(v) +} + +// UintToFloat32Ptr converts uint to *float32. +func UintToFloat32Ptr(v uint) *float32 { + r := UintToFloat32(v) + return &r +} + +// UintToFloat64 converts uint to float64. +func UintToFloat64(v uint) float64 { + return float64(v) +} + +// UintToFloat64Ptr converts uint to *float64. +func UintToFloat64Ptr(v uint) *float64 { + r := UintToFloat64(v) + return &r +} + +// UintToInt converts uint to int. +func UintToInt(v uint) (int, error) { + if Host64bit { + if v > uint(maxInt64) { + return 0, errOverflowValue + } + } else { + if v > math.MaxInt32 { + return 0, errOverflowValue + } + } + return int(v), nil +} + +// UintToIntPtr converts uint to *int. +func UintToIntPtr(v uint) (*int, error) { + r, err := UintToInt(v) + return &r, err +} + +// UintToInt8 converts uint to int8. +func UintToInt8(v uint) (int8, error) { + if v > math.MaxInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// UintToInt8Ptr converts uint to *int8. +func UintToInt8Ptr(v uint) (*int8, error) { + r, err := UintToInt8(v) + return &r, err +} + +// UintToInt16 converts uint to int16. +func UintToInt16(v uint) (int16, error) { + if v > math.MaxInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// UintToInt16Ptr converts uint to *int16. +func UintToInt16Ptr(v uint) (*int16, error) { + r, err := UintToInt16(v) + return &r, err +} + +// UintToInt32 converts uint to int32. +func UintToInt32(v uint) (int32, error) { + if v > math.MaxInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// UintToInt32Ptr converts uint to *int32. +func UintToInt32Ptr(v uint) (*int32, error) { + r, err := UintToInt32(v) + return &r, err +} + +// UintToInt64 converts uint to int64. +func UintToInt64(v uint) (int64, error) { + if Host64bit && v > uint(maxInt64) { + return 0, errOverflowValue + } + return int64(v), nil +} + +// UintToInt64Ptr converts uint to *int64. +func UintToInt64Ptr(v uint) (*int64, error) { + r, err := UintToInt64(v) + return &r, err +} + +// UintToUintPtr converts uint to *uint. +func UintToUintPtr(v uint) *uint { + return &v +} + +// UintToUint8 converts uint to uint8. +func UintToUint8(v uint) (uint8, error) { + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// UintToUint8Ptr converts uint to *uint8. +func UintToUint8Ptr(v uint) (*uint8, error) { + r, err := UintToUint8(v) + return &r, err +} + +// UintToUint16 converts uint to uint16. +func UintToUint16(v uint) (uint16, error) { + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// UintToUint16Ptr converts uint to *uint16. +func UintToUint16Ptr(v uint) (*uint16, error) { + r, err := UintToUint16(v) + return &r, err +} + +// UintToUint32 converts uint to uint32. +func UintToUint32(v uint) (uint32, error) { + if Host64bit && v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint32(v), nil +} + +// UintToUint32Ptr converts uint to *uint32. +func UintToUint32Ptr(v uint) (*uint32, error) { + r, err := UintToUint32(v) + return &r, err +} + +// UintToUint64 converts uint to uint64. +func UintToUint64(v uint) uint64 { + return uint64(v) +} + +// UintToUint64Ptr converts uint to *uint64. +func UintToUint64Ptr(v uint) *uint64 { + r := UintToUint64(v) + return &r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint16.go b/vendor/github.com/henrylee2cn/ameda/uint16.go new file mode 100644 index 0000000..3f2336e --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint16.go @@ -0,0 +1,174 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Uint16ToInterface converts uint16 to interface. +func Uint16ToInterface(v uint16) interface{} { + return v +} + +// Uint16ToInterfacePtr converts uint16 to *interface. +func Uint16ToInterfacePtr(v uint16) *interface{} { + r := Uint16ToInterface(v) + return &r +} + +// Uint16ToString converts uint16 to string. +func Uint16ToString(v uint16) string { + return strconv.FormatUint(uint64(v), 10) +} + +// Uint16ToStringPtr converts uint16 to *string. +func Uint16ToStringPtr(v uint16) *string { + r := Uint16ToString(v) + return &r +} + +// Uint16ToBool converts uint16 to bool. +func Uint16ToBool(v uint16) bool { + return v != 0 +} + +// Uint16ToBoolPtr converts uint16 to *bool. +func Uint16ToBoolPtr(v uint16) *bool { + r := Uint16ToBool(v) + return &r +} + +// Uint16ToFloat32 converts uint16 to float32. +func Uint16ToFloat32(v uint16) float32 { + return float32(v) +} + +// Uint16ToFloat32Ptr converts uint16 to *float32. +func Uint16ToFloat32Ptr(v uint16) *float32 { + r := Uint16ToFloat32(v) + return &r +} + +// Uint16ToFloat64 converts uint16 to float64. +func Uint16ToFloat64(v uint16) float64 { + return float64(v) +} + +// Uint16ToFloat64Ptr converts uint16 to *float64. +func Uint16ToFloat64Ptr(v uint16) *float64 { + r := Uint16ToFloat64(v) + return &r +} + +// Uint16ToInt converts uint16 to int. +func Uint16ToInt(v uint16) int { + return int(v) +} + +// Uint16ToIntPtr converts uint16 to *int. +func Uint16ToIntPtr(v uint16) *int { + r := Uint16ToInt(v) + return &r +} + +// Uint16ToInt8 converts uint16 to int8. +func Uint16ToInt8(v uint16) (int8, error) { + if v > math.MaxInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Uint16ToInt8Ptr converts uint16 to *int8. +func Uint16ToInt8Ptr(v uint16) (*int8, error) { + r, err := Uint16ToInt8(v) + return &r, err +} + +// Uint16ToInt16 converts uint16 to int16. +func Uint16ToInt16(v uint16) (int16, error) { + if v > math.MaxInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Uint16ToInt16Ptr converts uint16 to *int16. +func Uint16ToInt16Ptr(v uint16) (*int16, error) { + r, err := Uint16ToInt16(v) + return &r, err +} + +// Uint16ToInt32 converts uint16 to int32. +func Uint16ToInt32(v uint16) int32 { + return int32(v) +} + +// Uint16ToInt32Ptr converts uint16 to *int32. +func Uint16ToInt32Ptr(v uint16) *int32 { + r := Uint16ToInt32(v) + return &r +} + +// Uint16ToInt64 converts uint16 to int64. +func Uint16ToInt64(v uint16) int64 { + return int64(v) +} + +// Uint16ToInt64Ptr converts uint16 to *int64. +func Uint16ToInt64Ptr(v uint16) *int64 { + r := Uint16ToInt64(v) + return &r +} + +// Uint16ToUint converts uint16 to uint. +func Uint16ToUint(v uint16) uint { + return uint(v) +} + +// Uint16ToUintPtr converts uint16 to *uint. +func Uint16ToUintPtr(v uint16) *uint { + r := Uint16ToUint(v) + return &r +} + +// Uint16ToUint8 converts uint16 to uint8. +func Uint16ToUint8(v uint16) (uint8, error) { + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Uint16ToUint8Ptr converts uint16 to *uint8. +func Uint16ToUint8Ptr(v uint16) (*uint8, error) { + r, err := Uint16ToUint8(v) + return &r, err +} + +// Uint16ToUint16Ptr converts uint16 to *uint16. +func Uint16ToUint16Ptr(v uint16) *uint16 { + return &v +} + +// Uint16ToUint32 converts uint16 to uint32. +func Uint16ToUint32(v uint16) uint32 { + return uint32(v) +} + +// Uint16ToUint32Ptr converts uint16 to *uint32. +func Uint16ToUint32Ptr(v uint16) *uint32 { + r := Uint16ToUint32(v) + return &r +} + +// Uint16ToUint64 converts uint16 to uint64. +func Uint16ToUint64(v uint16) uint64 { + return uint64(v) +} + +// Uint16ToUint64Ptr converts uint16 to *uint64. +func Uint16ToUint64Ptr(v uint16) *uint64 { + r := Uint16ToUint64(v) + return &r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint16s.go b/vendor/github.com/henrylee2cn/ameda/uint16s.go new file mode 100644 index 0000000..af352d1 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint16s.go @@ -0,0 +1,668 @@ +package ameda + +// OneUint16 try to return the first element, otherwise return zero value. +func OneUint16(u []uint16) uint16 { + if len(u) > 0 { + return u[0] + } + return 0 +} + +// Uint16sCopy creates a copy of the uint16 slice. +func Uint16sCopy(u []uint16) []uint16 { + b := make([]uint16, len(u)) + copy(b, u) + return b +} + +// Uint16sToInterfaces converts uint16 slice to interface slice. +func Uint16sToInterfaces(u []uint16) []interface{} { + r := make([]interface{}, len(u)) + for k, v := range u { + r[k] = Uint16ToInterface(v) + } + return r +} + +// Uint16sToStrings converts uint16 slice to string slice. +func Uint16sToStrings(u []uint16) []string { + r := make([]string, len(u)) + for k, v := range u { + r[k] = Uint16ToString(v) + } + return r +} + +// Uint16sToBools converts uint16 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Uint16sToBools(u []uint16) []bool { + r := make([]bool, len(u)) + for k, v := range u { + r[k] = Uint16ToBool(v) + } + return r +} + +// Uint16sToFloat32s converts uint16 slice to float32 slice. +func Uint16sToFloat32s(u []uint16) []float32 { + r := make([]float32, len(u)) + for k, v := range u { + r[k] = Uint16ToFloat32(v) + } + return r +} + +// Uint16sToFloat64s converts uint16 slice to float64 slice. +func Uint16sToFloat64s(u []uint16) []float64 { + r := make([]float64, len(u)) + for k, v := range u { + r[k] = Uint16ToFloat64(v) + } + return r +} + +// Uint16sToInts converts uint16 slice to int slice. +func Uint16sToInts(u []uint16) []int { + r := make([]int, len(u)) + for k, v := range u { + r[k] = Uint16ToInt(v) + } + return r +} + +// Uint16sToInt8s converts uint16 slice to int8 slice. +func Uint16sToInt8s(u []uint16) ([]int8, error) { + var err error + r := make([]int8, len(u)) + for k, v := range u { + r[k], err = Uint16ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint16sToInt16s converts uint16 slice to int16 slice. +func Uint16sToInt16s(u []uint16) ([]int16, error) { + var err error + r := make([]int16, len(u)) + for k, v := range u { + r[k], err = Uint16ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint16sToInt32s converts uint16 slice to int32 slice. +func Uint16sToInt32s(u []uint16) []int32 { + r := make([]int32, len(u)) + for k, v := range u { + r[k] = Uint16ToInt32(v) + } + return r +} + +// Uint16sToInt64s converts uint16 slice to int64 slice. +func Uint16sToInt64s(u []uint16) []int64 { + r := make([]int64, len(u)) + for k, v := range u { + r[k] = Uint16ToInt64(v) + } + return r +} + +// Uint16sToUints converts uint16 slice to uint slice. +func Uint16sToUints(u []uint16) []uint { + r := make([]uint, len(u)) + for k, v := range u { + r[k] = Uint16ToUint(v) + } + return r +} + +// Uint16sToUint8s converts uint16 slice to uint8 slice. +func Uint16sToUint8s(u []uint16) ([]uint8, error) { + var err error + r := make([]uint8, len(u)) + for k, v := range u { + r[k], err = Uint16ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint16sToUint32s converts uint16 slice to uint32 slice. +func Uint16sToUint32s(u []uint16) []uint32 { + r := make([]uint32, len(u)) + for k, v := range u { + r[k] = Uint16ToUint32(v) + } + return r +} + +// Uint16sToUint64s converts uint16 slice to uint64 slice. +func Uint16sToUint64s(u []uint16) []uint64 { + r := make([]uint64, len(u)) + for k, v := range u { + r[k] = Uint16ToUint64(v) + } + return r +} + +// Uint16sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint16sCopyWithin(u []uint16, target, start int, end ...int) { + target = fixIndex(len(u), target, true) + if target == len(u) { + return + } + sub := Uint16sSlice(u, start, end...) + for k, v := range sub { + u[target+k] = v + } +} + +// Uint16sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Uint16sEvery(u []uint16, fn func(u []uint16, k int, v uint16) bool) bool { + for k, v := range u { + if !fn(u, k, v) { + return false + } + } + return true +} + +// Uint16sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint16sFill(u []uint16, value uint16, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + u[k] = value + } +} + +// Uint16sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Uint16sFilter(u []uint16, fn func(u []uint16, k int, v uint16) bool) []uint16 { + ret := make([]uint16, 0) + for k, v := range u { + if fn(u, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Uint16sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Uint16sFind(u []uint16, fn func(u []uint16, k int, v uint16) bool) (k int, v uint16) { + for k, v := range u { + if fn(u, k, v) { + return k, v + } + } + return -1, 0 +} + +// Uint16sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint16sIncludes(u []uint16, valueToFind uint16, fromIndex ...int) bool { + return Uint16sIndexOf(u, valueToFind, fromIndex...) > -1 +} + +// Uint16sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint16sIndexOf(u []uint16, searchElement uint16, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k, v := range u[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Uint16sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint16sLastIndexOf(u []uint16, searchElement uint16, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k := len(u) - 1; k >= idx; k-- { + if searchElement == u[k] { + return k + } + } + return -1 +} + +// Uint16sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Uint16sMap(u []uint16, fn func(u []uint16, k int, v uint16) uint16) []uint16 { + ret := make([]uint16, len(u)) + for k, v := range u { + ret[k] = fn(u, k, v) + } + return ret +} + +// Uint16sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Uint16sPop(u *[]uint16) (uint16, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *u = a[:len(a):len(a)] + return last, true +} + +// Uint16sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Uint16sPush(u *[]uint16, element ...uint16) int { + *u = append(*u, element...) + return len(*u) +} + +// Uint16sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Uint16sPushDistinct(u []uint16, element ...uint16) []uint16 { +L: + for _, v := range element { + for _, vv := range u { + if vv == v { + continue L + } + } + u = append(u, v) + } + return u +} + +// Uint16sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint16sReduce( + u []uint16, + fn func(u []uint16, k int, v, accumulator uint16) uint16, initialValue ...uint16, +) uint16 { + if len(u) == 0 { + return 0 + } + start := 0 + acc := u[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(u); k++ { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint16sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint16sReduceRight( + u []uint16, + fn func(u []uint16, k int, v, accumulator uint16) uint16, initialValue ...uint16, +) uint16 { + if len(u) == 0 { + return 0 + } + end := len(u) - 1 + acc := u[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint16sReverse reverses an slice in place. +func Uint16sReverse(u []uint16) { + first := 0 + last := len(u) - 1 + for first < last { + u[first], u[last] = u[last], u[first] + first++ + last-- + } +} + +// Uint16sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Uint16sShift(u *[]uint16) (uint16, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *u = a[:len(a):len(a)] + return first, true +} + +// Uint16sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Uint16sSlice(u []uint16, begin int, end ...int) []uint16 { + fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) + if !ok { + return []uint16{} + } + return Uint16sCopy(u[fixedStart:fixedEnd]) +} + +// Uint16sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Uint16sSome(u []uint16, fn func(u []uint16, k int, v uint16) bool) bool { + for k, v := range u { + if fn(u, k, v) { + return true + } + } + return false +} + +// Uint16sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Uint16sSplice(u *[]uint16, start, deleteCount int, items ...uint16) { + a := *u + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Uint16sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *u = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *u = a[:len(a):len(a)] +} + +// Uint16sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Uint16sUnshift(u *[]uint16, element ...uint16) int { + *u = append(element, *u...) + return len(*u) +} + +// Uint16sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Uint16sUnshiftDistinct(u *[]uint16, element ...uint16) int { + a := *u + if len(element) == 0 { + return len(a) + } + m := make(map[uint16]bool, len(element)) + r := make([]uint16, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *u = r[:len(r):len(r)] + return len(r) +} + +// Uint16sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Uint16sRemoveFirst(p *[]uint16, elements ...uint16) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint16sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Uint16sRemoveEvery(p *[]uint16, elements ...uint16) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint16sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Uint16sConcat(u ...[]uint16) []uint16 { + var totalLen int + for _, v := range u { + totalLen += len(v) + } + ret := make([]uint16, totalLen) + dst := ret + for _, v := range u { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Uint16sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Uint16sIntersect(u ...[]uint16) (intersectCount map[uint16]int) { + if len(u) == 0 { + return nil + } + for _, v := range u { + if len(v) == 0 { + return nil + } + } + counts := make([]map[uint16]int, len(u)) + for k, v := range u { + counts[k] = uint16sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Uint16sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Uint16sDistinct(i *[]uint16, changeSlice bool) (distinctCount map[uint16]int) { + if !changeSlice { + return uint16sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = uint16sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func uint16sDistinct(src []uint16, dst *[]uint16) map[uint16]int { + m := make(map[uint16]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Uint16SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint16SetUnion(set1, set2 []uint16, others ...[]uint16) []uint16 { + m := make(map[uint16]struct{}, len(set1)+len(set2)) + r := make([]uint16, 0, len(m)) + for _, set := range append([][]uint16{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Uint16SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint16SetIntersect(set1, set2 []uint16, others ...[]uint16) []uint16 { + sets := append([][]uint16{set2}, others...) + setsCount := make([]map[uint16]int, len(sets)) + for k, v := range sets { + setsCount[k] = uint16sDistinct(v, nil) + } + m := make(map[uint16]struct{}, len(set1)) + r := make([]uint16, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Uint16SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint16SetDifference(set1, set2 []uint16, others ...[]uint16) []uint16 { + m := make(map[uint16]struct{}, len(set1)) + r := make([]uint16, 0, len(set1)) + sets := append([][]uint16{set2}, others...) + for _, v := range sets { + inter := Uint16SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint32.go b/vendor/github.com/henrylee2cn/ameda/uint32.go new file mode 100644 index 0000000..63b9775 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint32.go @@ -0,0 +1,180 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Uint32ToInterface converts uint32 to interface. +func Uint32ToInterface(v uint32) interface{} { + return v +} + +// Uint32ToInterfacePtr converts uint32 to *interface. +func Uint32ToInterfacePtr(v uint32) *interface{} { + r := Uint32ToInterface(v) + return &r +} + +// Uint32ToString converts uint32 to string. +func Uint32ToString(v uint32) string { + return strconv.FormatUint(uint64(v), 10) +} + +// Uint32ToStringPtr converts uint32 to *string. +func Uint32ToStringPtr(v uint32) *string { + r := Uint32ToString(v) + return &r +} + +// Uint32ToBool converts uint32 to bool. +func Uint32ToBool(v uint32) bool { + return v != 0 +} + +// Uint32ToBoolPtr converts uint32 to *bool. +func Uint32ToBoolPtr(v uint32) *bool { + r := Uint32ToBool(v) + return &r +} + +// Uint32ToFloat32 converts uint32 to float32. +func Uint32ToFloat32(v uint32) float32 { + return float32(v) +} + +// Uint32ToFloat32Ptr converts uint32 to *float32. +func Uint32ToFloat32Ptr(v uint32) *float32 { + r := Uint32ToFloat32(v) + return &r +} + +// Uint32ToFloat64 converts uint32 to float64. +func Uint32ToFloat64(v uint32) float64 { + return float64(v) +} + +// Uint32ToFloat64Ptr converts uint32 to *float64. +func Uint32ToFloat64Ptr(v uint32) *float64 { + r := Uint32ToFloat64(v) + return &r +} + +// Uint32ToInt converts uint32 to int. +func Uint32ToInt(v uint32) int { + return int(v) +} + +// Uint32ToIntPtr converts uint32 to *int. +func Uint32ToIntPtr(v uint32) *int { + r := Uint32ToInt(v) + return &r +} + +// Uint32ToInt8 converts uint32 to int8. +func Uint32ToInt8(v uint32) (int8, error) { + if v > math.MaxInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Uint32ToInt8Ptr converts uint32 to *int8. +func Uint32ToInt8Ptr(v uint32) (*int8, error) { + r, err := Uint32ToInt8(v) + return &r, err +} + +// Uint32ToInt16 converts uint32 to int16. +func Uint32ToInt16(v uint32) (int16, error) { + if v > math.MaxInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Uint32ToInt16Ptr converts uint32 to *int16. +func Uint32ToInt16Ptr(v uint32) (*int16, error) { + r, err := Uint32ToInt16(v) + return &r, err +} + +// Uint32ToInt32 converts uint32 to int32. +func Uint32ToInt32(v uint32) (int32, error) { + if v > math.MaxInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// Uint32ToInt32Ptr converts uint32 to *int32. +func Uint32ToInt32Ptr(v uint32) (*int32, error) { + r, err := Uint32ToInt32(v) + return &r, err +} + +// Uint32ToInt64 converts uint32 to int64. +func Uint32ToInt64(v uint32) int64 { + return int64(v) +} + +// Uint32ToInt64Ptr converts uint32 to *int64. +func Uint32ToInt64Ptr(v uint32) *int64 { + r := Uint32ToInt64(v) + return &r +} + +// Uint32ToUint converts uint32 to uint. +func Uint32ToUint(v uint32) uint { + return uint(v) +} + +// Uint32ToUintPtr converts uint32 to *uint. +func Uint32ToUintPtr(v uint32) *uint { + r := Uint32ToUint(v) + return &r +} + +// Uint32ToUint8 converts uint32 to uint8. +func Uint32ToUint8(v uint32) (uint8, error) { + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Uint32ToUint8Ptr converts uint32 to *uint8. +func Uint32ToUint8Ptr(v uint32) (*uint8, error) { + r, err := Uint32ToUint8(v) + return &r, err +} + +// Uint32ToUint16 converts uint32 to uint16. +func Uint32ToUint16(v uint32) (uint16, error) { + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Uint32ToUint16Ptr converts uint32 to *uint16. +func Uint32ToUint16Ptr(v uint32) (*uint16, error) { + r, err := Uint32ToUint16(v) + return &r, err +} + +// Uint32ToUint32Ptr converts uint32 to *uint32. +func Uint32ToUint32Ptr(v uint32) *uint32 { + return &v +} + +// Uint32ToUint64 converts uint32 to uint64. +func Uint32ToUint64(v uint32) uint64 { + return uint64(v) +} + +// Uint32ToUint64Ptr converts uint32 to *uint64. +func Uint32ToUint64Ptr(v uint32) *uint64 { + r := Uint32ToUint64(v) + return &r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint32s.go b/vendor/github.com/henrylee2cn/ameda/uint32s.go new file mode 100644 index 0000000..075a305 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint32s.go @@ -0,0 +1,676 @@ +package ameda + +// OneUint32 try to return the first element, otherwise return zero value. +func OneUint32(u []uint32) uint32 { + if len(u) > 0 { + return u[0] + } + return 0 +} + +// Uint32sCopy creates a copy of the uint32 slice. +func Uint32sCopy(u []uint32) []uint32 { + b := make([]uint32, len(u)) + copy(b, u) + return b +} + +// Uint32sToInterfaces converts uint32 slice to interface slice. +func Uint32sToInterfaces(u []uint32) []interface{} { + r := make([]interface{}, len(u)) + for k, v := range u { + r[k] = Uint32ToInterface(v) + } + return r +} + +// Uint32sToStrings converts uint32 slice to string slice. +func Uint32sToStrings(u []uint32) []string { + r := make([]string, len(u)) + for k, v := range u { + r[k] = Uint32ToString(v) + } + return r +} + +// Uint32sToBools converts uint32 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Uint32sToBools(u []uint32) []bool { + r := make([]bool, len(u)) + for k, v := range u { + r[k] = Uint32ToBool(v) + } + return r +} + +// Uint32sToFloat32s converts uint32 slice to float32 slice. +func Uint32sToFloat32s(u []uint32) []float32 { + r := make([]float32, len(u)) + for k, v := range u { + r[k] = Uint32ToFloat32(v) + } + return r +} + +// Uint32sToFloat64s converts uint32 slice to float64 slice. +func Uint32sToFloat64s(u []uint32) []float64 { + r := make([]float64, len(u)) + for k, v := range u { + r[k] = Uint32ToFloat64(v) + } + return r +} + +// Uint32sToInts converts uint32 slice to int slice. +func Uint32sToInts(u []uint32) []int { + r := make([]int, len(u)) + for k, v := range u { + r[k] = Uint32ToInt(v) + } + return r +} + +// Uint32sToInt8s converts uint32 slice to int8 slice. +func Uint32sToInt8s(u []uint32) ([]int8, error) { + var err error + r := make([]int8, len(u)) + for k, v := range u { + r[k], err = Uint32ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint32sToInt16s converts uint32 slice to int16 slice. +func Uint32sToInt16s(u []uint32) ([]int16, error) { + var err error + r := make([]int16, len(u)) + for k, v := range u { + r[k], err = Uint32ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint32sToInt32s converts uint32 slice to int32 slice. +func Uint32sToInt32s(u []uint32) ([]int32, error) { + var err error + r := make([]int32, len(u)) + for k, v := range u { + r[k], err = Uint32ToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint32sToInt64s converts uint32 slice to int64 slice. +func Uint32sToInt64s(u []uint32) []int64 { + r := make([]int64, len(u)) + for k, v := range u { + r[k] = Uint32ToInt64(v) + } + return r +} + +// Uint32sToUints converts uint32 slice to uint slice. +func Uint32sToUints(u []uint32) []uint { + r := make([]uint, len(u)) + for k, v := range u { + r[k] = Uint32ToUint(v) + } + return r +} + +// Uint32sToUint8s converts uint32 slice to uint8 slice. +func Uint32sToUint8s(u []uint32) ([]uint8, error) { + var err error + r := make([]uint8, len(u)) + for k, v := range u { + r[k], err = Uint32ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint32sToUint16s converts uint32 slice to uint16 slice. +func Uint32sToUint16s(u []uint32) ([]uint16, error) { + var err error + r := make([]uint16, len(u)) + for k, v := range u { + r[k], err = Uint32ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint32sToUint64s converts uint32 slice to uint64 slice. +func Uint32sToUint64s(u []uint32) []uint64 { + r := make([]uint64, len(u)) + for k, v := range u { + r[k] = Uint32ToUint64(v) + } + return r +} + +// Uint32sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint32sCopyWithin(u []uint32, target, start int, end ...int) { + target = fixIndex(len(u), target, true) + if target == len(u) { + return + } + sub := Uint32sSlice(u, start, end...) + for k, v := range sub { + u[target+k] = v + } +} + +// Uint32sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Uint32sEvery(u []uint32, fn func(u []uint32, k int, v uint32) bool) bool { + for k, v := range u { + if !fn(u, k, v) { + return false + } + } + return true +} + +// Uint32sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint32sFill(u []uint32, value uint32, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + u[k] = value + } +} + +// Uint32sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Uint32sFilter(u []uint32, fn func(u []uint32, k int, v uint32) bool) []uint32 { + ret := make([]uint32, 0) + for k, v := range u { + if fn(u, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Uint32sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Uint32sFind(u []uint32, fn func(u []uint32, k int, v uint32) bool) (k int, v uint32) { + for k, v := range u { + if fn(u, k, v) { + return k, v + } + } + return -1, 0 +} + +// Uint32sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint32sIncludes(u []uint32, valueToFind uint32, fromIndex ...int) bool { + return Uint32sIndexOf(u, valueToFind, fromIndex...) > -1 +} + +// Uint32sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint32sIndexOf(u []uint32, searchElement uint32, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k, v := range u[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Uint32sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint32sLastIndexOf(u []uint32, searchElement uint32, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k := len(u) - 1; k >= idx; k-- { + if searchElement == u[k] { + return k + } + } + return -1 +} + +// Uint32sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Uint32sMap(u []uint32, fn func(u []uint32, k int, v uint32) uint32) []uint32 { + ret := make([]uint32, len(u)) + for k, v := range u { + ret[k] = fn(u, k, v) + } + return ret +} + +// Uint32sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Uint32sPop(u *[]uint32) (uint32, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *u = a[:len(a):len(a)] + return last, true +} + +// Uint32sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Uint32sPush(u *[]uint32, element ...uint32) int { + *u = append(*u, element...) + return len(*u) +} + +// Uint32sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Uint32sPushDistinct(u []uint32, element ...uint32) []uint32 { +L: + for _, v := range element { + for _, vv := range u { + if vv == v { + continue L + } + } + u = append(u, v) + } + return u +} + +// Uint32sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint32sReduce( + u []uint32, + fn func(u []uint32, k int, v, accumulator uint32) uint32, initialValue ...uint32, +) uint32 { + if len(u) == 0 { + return 0 + } + start := 0 + acc := u[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(u); k++ { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint32sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint32sReduceRight( + u []uint32, + fn func(u []uint32, k int, v, accumulator uint32) uint32, initialValue ...uint32, +) uint32 { + if len(u) == 0 { + return 0 + } + end := len(u) - 1 + acc := u[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint32sReverse reverses an slice in place. +func Uint32sReverse(u []uint32) { + first := 0 + last := len(u) - 1 + for first < last { + u[first], u[last] = u[last], u[first] + first++ + last-- + } +} + +// Uint32sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Uint32sShift(u *[]uint32) (uint32, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *u = a[:len(a):len(a)] + return first, true +} + +// Uint32sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Uint32sSlice(u []uint32, begin int, end ...int) []uint32 { + fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) + if !ok { + return []uint32{} + } + return Uint32sCopy(u[fixedStart:fixedEnd]) +} + +// Uint32sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Uint32sSome(u []uint32, fn func(u []uint32, k int, v uint32) bool) bool { + for k, v := range u { + if fn(u, k, v) { + return true + } + } + return false +} + +// Uint32sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Uint32sSplice(u *[]uint32, start, deleteCount int, items ...uint32) { + a := *u + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Uint32sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *u = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *u = a[:len(a):len(a)] +} + +// Uint32sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Uint32sUnshift(u *[]uint32, element ...uint32) int { + *u = append(element, *u...) + return len(*u) +} + +// Uint32sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Uint32sUnshiftDistinct(u *[]uint32, element ...uint32) int { + a := *u + if len(element) == 0 { + return len(a) + } + m := make(map[uint32]bool, len(element)) + r := make([]uint32, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *u = r[:len(r):len(r)] + return len(r) +} + +// Uint32sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Uint32sRemoveFirst(p *[]uint32, elements ...uint32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint32sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Uint32sRemoveEvery(p *[]uint32, elements ...uint32) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint32sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Uint32sConcat(u ...[]uint32) []uint32 { + var totalLen int + for _, v := range u { + totalLen += len(v) + } + ret := make([]uint32, totalLen) + dst := ret + for _, v := range u { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Uint32sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Uint32sIntersect(u ...[]uint32) (intersectCount map[uint32]int) { + if len(u) == 0 { + return nil + } + for _, v := range u { + if len(v) == 0 { + return nil + } + } + counts := make([]map[uint32]int, len(u)) + for k, v := range u { + counts[k] = uint32sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Uint32sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Uint32sDistinct(i *[]uint32, changeSlice bool) (distinctCount map[uint32]int) { + if !changeSlice { + return uint32sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = uint32sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func uint32sDistinct(src []uint32, dst *[]uint32) map[uint32]int { + m := make(map[uint32]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Uint32SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint32SetUnion(set1, set2 []uint32, others ...[]uint32) []uint32 { + m := make(map[uint32]struct{}, len(set1)+len(set2)) + r := make([]uint32, 0, len(m)) + for _, set := range append([][]uint32{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Uint32SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint32SetIntersect(set1, set2 []uint32, others ...[]uint32) []uint32 { + sets := append([][]uint32{set2}, others...) + setsCount := make([]map[uint32]int, len(sets)) + for k, v := range sets { + setsCount[k] = uint32sDistinct(v, nil) + } + m := make(map[uint32]struct{}, len(set1)) + r := make([]uint32, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Uint32SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint32SetDifference(set1, set2 []uint32, others ...[]uint32) []uint32 { + m := make(map[uint32]struct{}, len(set1)) + r := make([]uint32, 0, len(set1)) + sets := append([][]uint32{set2}, others...) + for _, v := range sets { + inter := Uint32SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint64.go b/vendor/github.com/henrylee2cn/ameda/uint64.go new file mode 100644 index 0000000..ece9446 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint64.go @@ -0,0 +1,189 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Uint64ToInterface converts uint64 to interface. +func Uint64ToInterface(v uint64) interface{} { + return v +} + +// Uint64ToInterfacePtr converts uint64 to *interface. +func Uint64ToInterfacePtr(v uint64) *interface{} { + r := Uint64ToInterface(v) + return &r +} + +// Uint64ToString converts uint64 to string. +func Uint64ToString(v uint64) string { + return strconv.FormatUint(uint64(v), 10) +} + +// Uint64ToStringPtr converts uint64 to *string. +func Uint64ToStringPtr(v uint64) *string { + r := Uint64ToString(v) + return &r +} + +// Uint64ToBool converts uint64 to bool. +func Uint64ToBool(v uint64) bool { + return v != 0 +} + +// Uint64ToBoolPtr converts uint64 to *bool. +func Uint64ToBoolPtr(v uint64) *bool { + r := Uint64ToBool(v) + return &r +} + +// Uint64ToFloat32 converts uint64 to float32. +func Uint64ToFloat32(v uint64) float32 { + return float32(v) +} + +// Uint64ToFloat32Ptr converts uint64 to *float32. +func Uint64ToFloat32Ptr(v uint64) *float32 { + r := Uint64ToFloat32(v) + return &r +} + +// Uint64ToFloat64 converts uint64 to float64. +func Uint64ToFloat64(v uint64) float64 { + return float64(v) +} + +// Uint64ToFloat64Ptr converts uint64 to *float64. +func Uint64ToFloat64Ptr(v uint64) *float64 { + r := Uint64ToFloat64(v) + return &r +} + +// Uint64ToInt converts uint64 to int. +func Uint64ToInt(v uint64) int { + return int(v) +} + +// Uint64ToIntPtr converts uint64 to *int. +func Uint64ToIntPtr(v uint64) *int { + r := Uint64ToInt(v) + return &r +} + +// Uint64ToInt8 converts uint64 to int8. +func Uint64ToInt8(v uint64) (int8, error) { + if v > math.MaxInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Uint64ToInt8Ptr converts uint64 to *int8. +func Uint64ToInt8Ptr(v uint64) (*int8, error) { + r, err := Uint64ToInt8(v) + return &r, err +} + +// Uint64ToInt16 converts uint64 to int16. +func Uint64ToInt16(v uint64) (int16, error) { + if v > math.MaxInt16 { + return 0, errOverflowValue + } + return int16(v), nil +} + +// Uint64ToInt16Ptr converts uint64 to *int16. +func Uint64ToInt16Ptr(v uint64) (*int16, error) { + r, err := Uint64ToInt16(v) + return &r, err +} + +// Uint64ToInt32 converts uint64 to int32. +func Uint64ToInt32(v uint64) (int32, error) { + if v > math.MaxInt32 { + return 0, errOverflowValue + } + return int32(v), nil +} + +// Uint64ToInt32Ptr converts uint64 to *int32. +func Uint64ToInt32Ptr(v uint64) (*int32, error) { + r, err := Uint64ToInt32(v) + return &r, err +} + +// Uint64ToInt64 converts uint64 to int64. +func Uint64ToInt64(v uint64) (int64, error) { + if v > math.MaxInt64 { + return 0, errOverflowValue + } + return int64(v), nil +} + +// Uint64ToInt64Ptr converts uint64 to *int64. +func Uint64ToInt64Ptr(v uint64) (*int64, error) { + r, err := Uint64ToInt64(v) + return &r, err +} + +// Uint64ToUint converts uint64 to uint. +func Uint64ToUint(v uint64) (uint, error) { + if !Host64bit && v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint(v), nil +} + +// Uint64ToUintPtr converts uint64 to *uint. +func Uint64ToUintPtr(v uint64) (*uint, error) { + r, err := Uint64ToUint(v) + return &r, err +} + +// Uint64ToUint8 converts uint64 to uint8. +func Uint64ToUint8(v uint64) (uint8, error) { + if v > math.MaxUint8 { + return 0, errOverflowValue + } + return uint8(v), nil +} + +// Uint64ToUint8Ptr converts uint64 to *uint8. +func Uint64ToUint8Ptr(v uint64) (*uint8, error) { + r, err := Uint64ToUint8(v) + return &r, err +} + +// Uint64ToUint16 converts uint64 to uint16. +func Uint64ToUint16(v uint64) (uint16, error) { + if v > math.MaxUint16 { + return 0, errOverflowValue + } + return uint16(v), nil +} + +// Uint64ToUint16Ptr converts uint64 to *uint16. +func Uint64ToUint16Ptr(v uint64) (*uint16, error) { + r, err := Uint64ToUint16(v) + return &r, err +} + +// Uint64ToUint32 converts uint64 to uint32. +func Uint64ToUint32(v uint64) (uint32, error) { + if v > math.MaxUint32 { + return 0, errOverflowValue + } + return uint32(v), nil +} + +// Uint64ToUint32Ptr converts uint64 to *uint32. +func Uint64ToUint32Ptr(v uint64) (*uint32, error) { + r, err := Uint64ToUint32(v) + return &r, err +} + +// Uint64ToUint64Ptr converts uint64 to *uint64. +func Uint64ToUint64Ptr(v uint64) *uint64 { + return &v +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint64s.go b/vendor/github.com/henrylee2cn/ameda/uint64s.go new file mode 100644 index 0000000..4a0f535 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint64s.go @@ -0,0 +1,688 @@ +package ameda + +// OneUint64 try to return the first element, otherwise return zero value. +func OneUint64(u []uint64) uint64 { + if len(u) > 0 { + return u[0] + } + return 0 +} + +// Uint64sCopy creates a copy of the uint64 slice. +func Uint64sCopy(u []uint64) []uint64 { + b := make([]uint64, len(u)) + copy(b, u) + return b +} + +// Uint64sToInterfaces converts uint64 slice to interface slice. +func Uint64sToInterfaces(u []uint64) []interface{} { + r := make([]interface{}, len(u)) + for k, v := range u { + r[k] = Uint64ToInterface(v) + } + return r +} + +// Uint64sToStrings converts uint64 slice to string slice. +func Uint64sToStrings(u []uint64) []string { + r := make([]string, len(u)) + for k, v := range u { + r[k] = Uint64ToString(v) + } + return r +} + +// Uint64sToBools converts uint64 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Uint64sToBools(u []uint64) []bool { + r := make([]bool, len(u)) + for k, v := range u { + r[k] = Uint64ToBool(v) + } + return r +} + +// Uint64sToFloat32s converts uint64 slice to float32 slice. +func Uint64sToFloat32s(u []uint64) []float32 { + r := make([]float32, len(u)) + for k, v := range u { + r[k] = Uint64ToFloat32(v) + } + return r +} + +// Uint64sToFloat64s converts uint64 slice to float64 slice. +func Uint64sToFloat64s(u []uint64) []float64 { + r := make([]float64, len(u)) + for k, v := range u { + r[k] = Uint64ToFloat64(v) + } + return r +} + +// Uint64sToInts converts uint64 slice to int slice. +func Uint64sToInts(u []uint64) []int { + r := make([]int, len(u)) + for k, v := range u { + r[k] = Uint64ToInt(v) + } + return r +} + +// Uint64sToInt8s converts uint64 slice to int8 slice. +func Uint64sToInt8s(u []uint64) ([]int8, error) { + var err error + r := make([]int8, len(u)) + for k, v := range u { + r[k], err = Uint64ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToInt16s converts uint64 slice to int16 slice. +func Uint64sToInt16s(u []uint64) ([]int16, error) { + var err error + r := make([]int16, len(u)) + for k, v := range u { + r[k], err = Uint64ToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToInt32s converts uint64 slice to int32 slice. +func Uint64sToInt32s(u []uint64) ([]int32, error) { + var err error + r := make([]int32, len(u)) + for k, v := range u { + r[k], err = Uint64ToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToInt64s converts uint64 slice to int64 slice. +func Uint64sToInt64s(u []uint64) ([]int64, error) { + var err error + r := make([]int64, len(u)) + for k, v := range u { + r[k], err = Uint64ToInt64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToUints converts uint64 slice to uint slice. +func Uint64sToUints(u []uint64) ([]uint, error) { + var err error + r := make([]uint, len(u)) + for k, v := range u { + r[k], err = Uint64ToUint(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToUint8s converts uint64 slice to uint8 slice. +func Uint64sToUint8s(u []uint64) ([]uint8, error) { + var err error + r := make([]uint8, len(u)) + for k, v := range u { + r[k], err = Uint64ToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToUint16s converts uint64 slice to uint16 slice. +func Uint64sToUint16s(u []uint64) ([]uint16, error) { + var err error + r := make([]uint16, len(u)) + for k, v := range u { + r[k], err = Uint64ToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sToUint32s converts uint64 slice to uint32 slice. +func Uint64sToUint32s(u []uint64) ([]uint32, error) { + var err error + r := make([]uint32, len(u)) + for k, v := range u { + r[k], err = Uint64ToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint64sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint64sCopyWithin(u []uint64, target, start int, end ...int) { + target = fixIndex(len(u), target, true) + if target == len(u) { + return + } + sub := Uint64sSlice(u, start, end...) + for k, v := range sub { + u[target+k] = v + } +} + +// Uint64sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Uint64sEvery(u []uint64, fn func(u []uint64, k int, v uint64) bool) bool { + for k, v := range u { + if !fn(u, k, v) { + return false + } + } + return true +} + +// Uint64sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint64sFill(u []uint64, value uint64, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + u[k] = value + } +} + +// Uint64sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Uint64sFilter(u []uint64, fn func(u []uint64, k int, v uint64) bool) []uint64 { + ret := make([]uint64, 0) + for k, v := range u { + if fn(u, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Uint64sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Uint64sFind(u []uint64, fn func(u []uint64, k int, v uint64) bool) (k int, v uint64) { + for k, v := range u { + if fn(u, k, v) { + return k, v + } + } + return -1, 0 +} + +// Uint64sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint64sIncludes(u []uint64, valueToFind uint64, fromIndex ...int) bool { + return Uint64sIndexOf(u, valueToFind, fromIndex...) > -1 +} + +// Uint64sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint64sIndexOf(u []uint64, searchElement uint64, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k, v := range u[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Uint64sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint64sLastIndexOf(u []uint64, searchElement uint64, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k := len(u) - 1; k >= idx; k-- { + if searchElement == u[k] { + return k + } + } + return -1 +} + +// Uint64sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Uint64sMap(u []uint64, fn func(u []uint64, k int, v uint64) uint64) []uint64 { + ret := make([]uint64, len(u)) + for k, v := range u { + ret[k] = fn(u, k, v) + } + return ret +} + +// Uint64sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Uint64sPop(u *[]uint64) (uint64, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *u = a[:len(a):len(a)] + return last, true +} + +// Uint64sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Uint64sPush(u *[]uint64, element ...uint64) int { + *u = append(*u, element...) + return len(*u) +} + +// Uint64sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Uint64sPushDistinct(u []uint64, element ...uint64) []uint64 { +L: + for _, v := range element { + for _, vv := range u { + if vv == v { + continue L + } + } + u = append(u, v) + } + return u +} + +// Uint64sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint64sReduce( + u []uint64, + fn func(u []uint64, k int, v, accumulator uint64) uint64, initialValue ...uint64, +) uint64 { + if len(u) == 0 { + return 0 + } + start := 0 + acc := u[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(u); k++ { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint64sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint64sReduceRight( + u []uint64, + fn func(u []uint64, k int, v, accumulator uint64) uint64, initialValue ...uint64, +) uint64 { + if len(u) == 0 { + return 0 + } + end := len(u) - 1 + acc := u[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint64sReverse reverses an slice in place. +func Uint64sReverse(u []uint64) { + first := 0 + last := len(u) - 1 + for first < last { + u[first], u[last] = u[last], u[first] + first++ + last-- + } +} + +// Uint64sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Uint64sShift(u *[]uint64) (uint64, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *u = a[:len(a):len(a)] + return first, true +} + +// Uint64sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Uint64sSlice(u []uint64, begin int, end ...int) []uint64 { + fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) + if !ok { + return []uint64{} + } + return Uint64sCopy(u[fixedStart:fixedEnd]) +} + +// Uint64sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Uint64sSome(u []uint64, fn func(u []uint64, k int, v uint64) bool) bool { + for k, v := range u { + if fn(u, k, v) { + return true + } + } + return false +} + +// Uint64sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Uint64sSplice(u *[]uint64, start, deleteCount int, items ...uint64) { + a := *u + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Uint64sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *u = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *u = a[:len(a):len(a)] +} + +// Uint64sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Uint64sUnshift(u *[]uint64, element ...uint64) int { + *u = append(element, *u...) + return len(*u) +} + +// Uint64sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Uint64sUnshiftDistinct(u *[]uint64, element ...uint64) int { + a := *u + if len(element) == 0 { + return len(a) + } + m := make(map[uint64]bool, len(element)) + r := make([]uint64, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *u = r[:len(r):len(r)] + return len(r) +} + +// Uint64sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Uint64sRemoveFirst(p *[]uint64, elements ...uint64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint64sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Uint64sRemoveEvery(p *[]uint64, elements ...uint64) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint64sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Uint64sConcat(u ...[]uint64) []uint64 { + var totalLen int + for _, v := range u { + totalLen += len(v) + } + ret := make([]uint64, totalLen) + dst := ret + for _, v := range u { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Uint64sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Uint64sIntersect(u ...[]uint64) (intersectCount map[uint64]int) { + if len(u) == 0 { + return nil + } + for _, v := range u { + if len(v) == 0 { + return nil + } + } + counts := make([]map[uint64]int, len(u)) + for k, v := range u { + counts[k] = uint64sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Uint64sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Uint64sDistinct(i *[]uint64, changeSlice bool) (distinctCount map[uint64]int) { + if !changeSlice { + return uint64sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = uint64sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func uint64sDistinct(src []uint64, dst *[]uint64) map[uint64]int { + m := make(map[uint64]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Uint64SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint64SetUnion(set1, set2 []uint64, others ...[]uint64) []uint64 { + m := make(map[uint64]struct{}, len(set1)+len(set2)) + r := make([]uint64, 0, len(m)) + for _, set := range append([][]uint64{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Uint64SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint64SetIntersect(set1, set2 []uint64, others ...[]uint64) []uint64 { + sets := append([][]uint64{set2}, others...) + setsCount := make([]map[uint64]int, len(sets)) + for k, v := range sets { + setsCount[k] = uint64sDistinct(v, nil) + } + m := make(map[uint64]struct{}, len(set1)) + r := make([]uint64, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Uint64SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint64SetDifference(set1, set2 []uint64, others ...[]uint64) []uint64 { + m := make(map[uint64]struct{}, len(set1)) + r := make([]uint64, 0, len(set1)) + sets := append([][]uint64{set2}, others...) + for _, v := range sets { + inter := Uint64SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint8.go b/vendor/github.com/henrylee2cn/ameda/uint8.go new file mode 100644 index 0000000..bb2d939 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint8.go @@ -0,0 +1,168 @@ +package ameda + +import ( + "math" + "strconv" +) + +// Uint8ToInterface converts uint8 to interface. +func Uint8ToInterface(v uint8) interface{} { + return v +} + +// Uint8ToInterfacePtr converts uint8 to *interface. +func Uint8ToInterfacePtr(v uint8) *interface{} { + r := Uint8ToInterface(v) + return &r +} + +// Uint8ToString converts uint8 to string. +func Uint8ToString(v uint8) string { + return strconv.FormatUint(uint64(v), 10) +} + +// Uint8ToStringPtr converts uint8 to *string. +func Uint8ToStringPtr(v uint8) *string { + r := Uint8ToString(v) + return &r +} + +// Uint8ToBool converts uint8 to bool. +func Uint8ToBool(v uint8) bool { + return v != 0 +} + +// Uint8ToBoolPtr converts uint8 to *bool. +func Uint8ToBoolPtr(v uint8) *bool { + r := Uint8ToBool(v) + return &r +} + +// Uint8ToFloat32 converts uint8 to float32. +func Uint8ToFloat32(v uint8) float32 { + return float32(v) +} + +// Uint8ToFloat32Ptr converts uint8 to *float32. +func Uint8ToFloat32Ptr(v uint8) *float32 { + r := Uint8ToFloat32(v) + return &r +} + +// Uint8ToFloat64 converts uint8 to float64. +func Uint8ToFloat64(v uint8) float64 { + return float64(v) +} + +// Uint8ToFloat64Ptr converts uint8 to *float64. +func Uint8ToFloat64Ptr(v uint8) *float64 { + r := Uint8ToFloat64(v) + return &r +} + +// Uint8ToInt converts uint8 to int. +func Uint8ToInt(v uint8) int { + return int(v) +} + +// Uint8ToIntPtr converts uint8 to *int. +func Uint8ToIntPtr(v uint8) *int { + r := Uint8ToInt(v) + return &r +} + +// Uint8ToInt8 converts uint8 to int8. +func Uint8ToInt8(v uint8) (int8, error) { + if v > math.MaxInt8 { + return 0, errOverflowValue + } + return int8(v), nil +} + +// Uint8ToInt8Ptr converts uint8 to *int8. +func Uint8ToInt8Ptr(v uint8) (*int8, error) { + r, err := Uint8ToInt8(v) + return &r, err +} + +// Uint8ToInt16 converts uint8 to int16. +func Uint8ToInt16(v uint8) int16 { + return int16(v) +} + +// Uint8ToInt16Ptr converts uint8 to *int16. +func Uint8ToInt16Ptr(v uint8) *int16 { + r := Uint8ToInt16(v) + return &r +} + +// Uint8ToInt32 converts uint8 to int32. +func Uint8ToInt32(v uint8) int32 { + return int32(v) +} + +// Uint8ToInt32Ptr converts uint8 to *int32. +func Uint8ToInt32Ptr(v uint8) *int32 { + r := Uint8ToInt32(v) + return &r +} + +// Uint8ToInt64 converts uint8 to int64. +func Uint8ToInt64(v uint8) int64 { + return int64(v) +} + +// Uint8ToInt64Ptr converts uint8 to *int64. +func Uint8ToInt64Ptr(v uint8) *int64 { + r := Uint8ToInt64(v) + return &r +} + +// Uint8ToUint converts uint8 to uint. +func Uint8ToUint(v uint8) uint { + return uint(v) +} + +// Uint8ToUintPtr converts uint8 to *uint. +func Uint8ToUintPtr(v uint8) *uint { + r := Uint8ToUint(v) + return &r +} + +// Uint8ToUint8Ptr converts uint8 to *uint8. +func Uint8ToUint8Ptr(v uint8) *uint8 { + return &v +} + +// Uint8ToUint16 converts uint8 to uint16. +func Uint8ToUint16(v uint8) uint16 { + return uint16(v) +} + +// Uint8ToUint16Ptr converts uint8 to *uint16. +func Uint8ToUint16Ptr(v uint8) *uint16 { + r := Uint8ToUint16(v) + return &r +} + +// Uint8ToUint32 converts uint8 to uint32. +func Uint8ToUint32(v uint8) uint32 { + return uint32(v) +} + +// Uint8ToUint32Ptr converts uint8 to *uint32. +func Uint8ToUint32Ptr(v uint8) *uint32 { + r := Uint8ToUint32(v) + return &r +} + +// Uint8ToUint64 converts uint8 to uint64. +func Uint8ToUint64(v uint8) uint64 { + return uint64(v) +} + +// Uint8ToUint64Ptr converts uint8 to *uint64. +func Uint8ToUint64Ptr(v uint8) *uint64 { + r := Uint8ToUint64(v) + return &r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uint8s.go b/vendor/github.com/henrylee2cn/ameda/uint8s.go new file mode 100644 index 0000000..c30964a --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uint8s.go @@ -0,0 +1,658 @@ +package ameda + +// OneUint8 try to return the first element, otherwise return zero value. +func OneUint8(u []uint8) uint8 { + if len(u) > 0 { + return u[0] + } + return 0 +} + +// Uint8sCopy creates a copy of the uint8 slice. +func Uint8sCopy(u []uint8) []uint8 { + b := make([]uint8, len(u)) + copy(b, u) + return b +} + +// Uint8sToInterfaces converts uint8 slice to interface slice. +func Uint8sToInterfaces(u []uint8) []interface{} { + r := make([]interface{}, len(u)) + for k, v := range u { + r[k] = Uint8ToInterface(v) + } + return r +} + +// Uint8sToStrings converts uint8 slice to string slice. +func Uint8sToStrings(u []uint8) []string { + r := make([]string, len(u)) + for k, v := range u { + r[k] = Uint8ToString(v) + } + return r +} + +// Uint8sToBools converts uint8 slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func Uint8sToBools(u []uint8) []bool { + r := make([]bool, len(u)) + for k, v := range u { + r[k] = Uint8ToBool(v) + } + return r +} + +// Uint8sToFloat32s converts uint8 slice to float32 slice. +func Uint8sToFloat32s(u []uint8) []float32 { + r := make([]float32, len(u)) + for k, v := range u { + r[k] = Uint8ToFloat32(v) + } + return r +} + +// Uint8sToFloat64s converts uint8 slice to float64 slice. +func Uint8sToFloat64s(u []uint8) []float64 { + r := make([]float64, len(u)) + for k, v := range u { + r[k] = Uint8ToFloat64(v) + } + return r +} + +// Uint8sToInts converts uint8 slice to int slice. +func Uint8sToInts(u []uint8) []int { + r := make([]int, len(u)) + for k, v := range u { + r[k] = Uint8ToInt(v) + } + return r +} + +// Uint8sToInt8s converts uint8 slice to int8 slice. +func Uint8sToInt8s(u []uint8) ([]int8, error) { + var err error + r := make([]int8, len(u)) + for k, v := range u { + r[k], err = Uint8ToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// Uint8sToInt16s converts uint8 slice to int16 slice. +func Uint8sToInt16s(u []uint8) []int16 { + r := make([]int16, len(u)) + for k, v := range u { + r[k] = Uint8ToInt16(v) + } + return r +} + +// Uint8sToInt32s converts uint8 slice to int32 slice. +func Uint8sToInt32s(u []uint8) []int32 { + r := make([]int32, len(u)) + for k, v := range u { + r[k] = Uint8ToInt32(v) + } + return r +} + +// Uint8sToInt64s converts uint8 slice to int64 slice. +func Uint8sToInt64s(u []uint8) []int64 { + r := make([]int64, len(u)) + for k, v := range u { + r[k] = Uint8ToInt64(v) + } + return r +} + +// Uint8sToUints converts uint8 slice to uint slice. +func Uint8sToUints(u []uint8) []uint { + r := make([]uint, len(u)) + for k, v := range u { + r[k] = Uint8ToUint(v) + } + return r +} + +// Uint8sToUint16s converts uint8 slice to uint16 slice. +func Uint8sToUint16s(u []uint8) []uint16 { + r := make([]uint16, len(u)) + for k, v := range u { + r[k] = Uint8ToUint16(v) + } + return r +} + +// Uint8sToUint32s converts uint8 slice to uint32 slice. +func Uint8sToUint32s(u []uint8) []uint32 { + r := make([]uint32, len(u)) + for k, v := range u { + r[k] = Uint8ToUint32(v) + } + return r +} + +// Uint8sToUint64s converts uint8 slice to uint64 slice. +func Uint8sToUint64s(u []uint8) []uint64 { + r := make([]uint64, len(u)) + for k, v := range u { + r[k] = Uint8ToUint64(v) + } + return r +} + +// Uint8sCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint8sCopyWithin(u []uint8, target, start int, end ...int) { + target = fixIndex(len(u), target, true) + if target == len(u) { + return + } + sub := Uint8sSlice(u, start, end...) + for k, v := range sub { + u[target+k] = v + } +} + +// Uint8sEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func Uint8sEvery(u []uint8, fn func(u []uint8, k int, v uint8) bool) bool { + for k, v := range u { + if !fn(u, k, v) { + return false + } + } + return true +} + +// Uint8sFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func Uint8sFill(u []uint8, value uint8, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + u[k] = value + } +} + +// Uint8sFilter creates a new slice with all elements that pass the test implemented by the provided function. +func Uint8sFilter(u []uint8, fn func(u []uint8, k int, v uint8) bool) []uint8 { + ret := make([]uint8, 0) + for k, v := range u { + if fn(u, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// Uint8sFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func Uint8sFind(u []uint8, fn func(u []uint8, k int, v uint8) bool) (k int, v uint8) { + for k, v := range u { + if fn(u, k, v) { + return k, v + } + } + return -1, 0 +} + +// Uint8sIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint8sIncludes(u []uint8, valueToFind uint8, fromIndex ...int) bool { + return Uint8sIndexOf(u, valueToFind, fromIndex...) > -1 +} + +// Uint8sIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint8sIndexOf(u []uint8, searchElement uint8, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k, v := range u[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// Uint8sLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func Uint8sLastIndexOf(u []uint8, searchElement uint8, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k := len(u) - 1; k >= idx; k-- { + if searchElement == u[k] { + return k + } + } + return -1 +} + +// Uint8sMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func Uint8sMap(u []uint8, fn func(u []uint8, k int, v uint8) uint8) []uint8 { + ret := make([]uint8, len(u)) + for k, v := range u { + ret[k] = fn(u, k, v) + } + return ret +} + +// Uint8sPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func Uint8sPop(u *[]uint8) (uint8, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *u = a[:len(a):len(a)] + return last, true +} + +// Uint8sPush adds one or more elements to the end of an slice and returns the new length of the slice. +func Uint8sPush(u *[]uint8, element ...uint8) int { + *u = append(*u, element...) + return len(*u) +} + +// Uint8sPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func Uint8sPushDistinct(u []uint8, element ...uint8) []uint8 { +L: + for _, v := range element { + for _, vv := range u { + if vv == v { + continue L + } + } + u = append(u, v) + } + return u +} + +// Uint8sReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint8sReduce(u []uint8, + fn func(u []uint8, k int, v, accumulator uint8) uint8, initialValue ...uint8, +) uint8 { + if len(u) == 0 { + return 0 + } + start := 0 + acc := u[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(u); k++ { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint8sReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func Uint8sReduceRight(u []uint8, + fn func(u []uint8, k int, v, accumulator uint8) uint8, initialValue ...uint8, +) uint8 { + if len(u) == 0 { + return 0 + } + end := len(u) - 1 + acc := u[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// Uint8sReverse reverses an slice in place. +func Uint8sReverse(u []uint8) { + first := 0 + last := len(u) - 1 + for first < last { + u[first], u[last] = u[last], u[first] + first++ + last-- + } +} + +// Uint8sShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func Uint8sShift(u *[]uint8) (uint8, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *u = a[:len(a):len(a)] + return first, true +} + +// Uint8sSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func Uint8sSlice(u []uint8, begin int, end ...int) []uint8 { + fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) + if !ok { + return []uint8{} + } + return Uint8sCopy(u[fixedStart:fixedEnd]) +} + +// Uint8sSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func Uint8sSome(u []uint8, fn func(u []uint8, k int, v uint8) bool) bool { + for k, v := range u { + if fn(u, k, v) { + return true + } + } + return false +} + +// Uint8sSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func Uint8sSplice(u *[]uint8, start, deleteCount int, items ...uint8) { + a := *u + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := Uint8sCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *u = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *u = a[:len(a):len(a)] +} + +// Uint8sUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func Uint8sUnshift(u *[]uint8, element ...uint8) int { + *u = append(element, *u...) + return len(*u) +} + +// Uint8sUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func Uint8sUnshiftDistinct(u *[]uint8, element ...uint8) int { + a := *u + if len(element) == 0 { + return len(a) + } + m := make(map[uint8]bool, len(element)) + r := make([]uint8, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *u = r[:len(r):len(r)] + return len(r) +} + +// Uint8sRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func Uint8sRemoveFirst(p *[]uint8, elements ...uint8) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint8sRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func Uint8sRemoveEvery(p *[]uint8, elements ...uint8) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// Uint8sConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func Uint8sConcat(u ...[]uint8) []uint8 { + var totalLen int + for _, v := range u { + totalLen += len(v) + } + ret := make([]uint8, totalLen) + dst := ret + for _, v := range u { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// Uint8sIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func Uint8sIntersect(u ...[]uint8) (intersectCount map[uint8]int) { + if len(u) == 0 { + return nil + } + for _, v := range u { + if len(v) == 0 { + return nil + } + } + counts := make([]map[uint8]int, len(u)) + for k, v := range u { + counts[k] = uint8sDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// Uint8sDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func Uint8sDistinct(i *[]uint8, changeSlice bool) (distinctCount map[uint8]int) { + if !changeSlice { + return uint8sDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = uint8sDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func uint8sDistinct(src []uint8, dst *[]uint8) map[uint8]int { + m := make(map[uint8]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// Uint8SetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint8SetUnion(set1, set2 []uint8, others ...[]uint8) []uint8 { + m := make(map[uint8]struct{}, len(set1)+len(set2)) + r := make([]uint8, 0, len(m)) + for _, set := range append([][]uint8{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// Uint8SetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint8SetIntersect(set1, set2 []uint8, others ...[]uint8) []uint8 { + sets := append([][]uint8{set2}, others...) + setsCount := make([]map[uint8]int, len(sets)) + for k, v := range sets { + setsCount[k] = uint8sDistinct(v, nil) + } + m := make(map[uint8]struct{}, len(set1)) + r := make([]uint8, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// Uint8SetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func Uint8SetDifference(set1, set2 []uint8, others ...[]uint8) []uint8 { + m := make(map[uint8]struct{}, len(set1)) + r := make([]uint8, 0, len(set1)) + sets := append([][]uint8{set2}, others...) + for _, v := range sets { + inter := Uint8SetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/uints.go b/vendor/github.com/henrylee2cn/ameda/uints.go new file mode 100644 index 0000000..c42d101 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/uints.go @@ -0,0 +1,686 @@ +package ameda + +// OneUint try to return the first element, otherwise return zero value. +func OneUint(u []uint) uint { + if len(u) > 0 { + return u[0] + } + return 0 +} + +// UintsCopy creates a copy of the uint slice. +func UintsCopy(u []uint) []uint { + b := make([]uint, len(u)) + copy(b, u) + return b +} + +// UintsToInterfaces converts uint slice to interface slice. +func UintsToInterfaces(u []uint) []interface{} { + r := make([]interface{}, len(u)) + for k, v := range u { + r[k] = UintToInterface(v) + } + return r +} + +// UintsToStrings converts uint slice to string slice. +func UintsToStrings(u []uint) []string { + r := make([]string, len(u)) + for k, v := range u { + r[k] = UintToString(v) + } + return r +} + +// UintsToBools converts uint slice to bool slice. +// NOTE: +// 0 is false, everything else is true +func UintsToBools(u []uint) []bool { + r := make([]bool, len(u)) + for k, v := range u { + r[k] = UintToBool(v) + } + return r +} + +// UintsToFloat32s converts uint slice to float32 slice. +func UintsToFloat32s(u []uint) []float32 { + r := make([]float32, len(u)) + for k, v := range u { + r[k] = UintToFloat32(v) + } + return r +} + +// UintsToFloat64s converts uint slice to float64 slice. +func UintsToFloat64s(u []uint) []float64 { + r := make([]float64, len(u)) + for k, v := range u { + r[k] = UintToFloat64(v) + } + return r +} + +// UintsToInts converts uint slice to int slice. +func UintsToInts(u []uint) ([]int, error) { + var err error + r := make([]int, len(u)) + for k, v := range u { + r[k], err = UintToInt(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToInt8s converts uint slice to int8 slice. +func UintsToInt8s(u []uint) ([]int8, error) { + var err error + r := make([]int8, len(u)) + for k, v := range u { + r[k], err = UintToInt8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToInt16s converts uint slice to int16 slice. +func UintsToInt16s(u []uint) ([]int16, error) { + var err error + r := make([]int16, len(u)) + for k, v := range u { + r[k], err = UintToInt16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToInt32s converts uint slice to int32 slice. +func UintsToInt32s(u []uint) ([]int32, error) { + var err error + r := make([]int32, len(u)) + for k, v := range u { + r[k], err = UintToInt32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToInt64s converts uint slice to int64 slice. +func UintsToInt64s(u []uint) ([]int64, error) { + var err error + r := make([]int64, len(u)) + for k, v := range u { + r[k], err = UintToInt64(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToUint8s converts uint slice to uint8 slice. +func UintsToUint8s(u []uint) ([]uint8, error) { + var err error + r := make([]uint8, len(u)) + for k, v := range u { + r[k], err = UintToUint8(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToUint16s converts uint slice to uint16 slice. +func UintsToUint16s(u []uint) ([]uint16, error) { + var err error + r := make([]uint16, len(u)) + for k, v := range u { + r[k], err = UintToUint16(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToUint32s converts uint slice to uint32 slice. +func UintsToUint32s(u []uint) ([]uint32, error) { + var err error + r := make([]uint32, len(u)) + for k, v := range u { + r[k], err = UintToUint32(v) + if err != nil { + return r, err + } + } + return r, nil +} + +// UintsToUint64s converts uint slice to uint64 slice. +func UintsToUint64s(u []uint) []uint64 { + r := make([]uint64, len(u)) + for k, v := range u { + r[k] = UintToUint64(v) + } + return r +} + +// UintsCopyWithin copies part of an slice to another location in the current slice. +// @target +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func UintsCopyWithin(u []uint, target, start int, end ...int) { + target = fixIndex(len(u), target, true) + if target == len(u) { + return + } + sub := UintsSlice(u, start, end...) + for k, v := range sub { + u[target+k] = v + } +} + +// UintsEvery tests whether all elements in the slice pass the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice will return true for any condition! +func UintsEvery(u []uint, fn func(u []uint, k int, v uint) bool) bool { + for k, v := range u { + if !fn(u, k, v) { + return false + } + } + return true +} + +// UintsFill changes all elements in the current slice to a value, from a start index to an end index. +// @value +// Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. +// @start +// Zero-based index at which to start copying elements from. If negative, start will be counted from the end. +// @end +// Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. +// If negative, end will be counted from the end. +// If end is omitted, CopyWithin will copy until the last index (default to len(s)). +func UintsFill(u []uint, value uint, start int, end ...int) { + fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) + if !ok { + return + } + for k := fixedStart; k < fixedEnd; k++ { + u[k] = value + } +} + +// UintsFilter creates a new slice with all elements that pass the test implemented by the provided function. +func UintsFilter(u []uint, fn func(u []uint, k int, v uint) bool) []uint { + ret := make([]uint, 0) + for k, v := range u { + if fn(u, k, v) { + ret = append(ret, v) + } + } + return ret +} + +// UintsFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. +// NOTE: +// If not found, k = -1 +func UintsFind(u []uint, fn func(u []uint, k int, v uint) bool) (k int, v uint) { + for k, v := range u { + if fn(u, k, v) { + return k, v + } + } + return -1, 0 +} + +// UintsIncludes determines whether an slice includes a certain value among its entries. +// @fromIndex +// The index to start the search at. Defaults to 0. +func UintsIncludes(u []uint, valueToFind uint, fromIndex ...int) bool { + return UintsIndexOf(u, valueToFind, fromIndex...) > -1 +} + +// UintsIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func UintsIndexOf(u []uint, searchElement uint, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k, v := range u[idx:] { + if searchElement == v { + return k + idx + } + } + return -1 +} + +// UintsLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. +// @fromIndex +// The index to start the search at. Defaults to 0. +func UintsLastIndexOf(u []uint, searchElement uint, fromIndex ...int) int { + idx := getFromIndex(len(u), fromIndex...) + for k := len(u) - 1; k >= idx; k-- { + if searchElement == u[k] { + return k + } + } + return -1 +} + +// UintsMap creates a new slice populated with the results of calling a provided function +// on every element in the calling slice. +func UintsMap(u []uint, fn func(u []uint, k int, v uint) uint) []uint { + ret := make([]uint, len(u)) + for k, v := range u { + ret[k] = fn(u, k, v) + } + return ret +} + +// UintsPop removes the last element from an slice and returns that element. +// This method changes the length of the slice. +func UintsPop(u *[]uint) (uint, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + lastIndex := len(a) - 1 + last := a[lastIndex] + a = a[:lastIndex] + *u = a[:len(a):len(a)] + return last, true +} + +// UintsPush adds one or more elements to the end of an slice and returns the new length of the slice. +func UintsPush(u *[]uint, element ...uint) int { + *u = append(*u, element...) + return len(*u) +} + +// UintsPushDistinct adds one or more new elements that do not exist in the current slice at the end. +func UintsPushDistinct(u []uint, element ...uint) []uint { +L: + for _, v := range element { + for _, vv := range u { + if vv == v { + continue L + } + } + u = append(u, v) + } + return u +} + +// UintsReduce executes a reducer function (that you provide) on each element of the slice, +// resulting in a single output value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func UintsReduce(u []uint, + fn func(u []uint, k int, v, accumulator uint) uint, initialValue ...uint, +) uint { + if len(u) == 0 { + return 0 + } + start := 0 + acc := u[start] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + start += 1 + } + for k := start; k < len(u); k++ { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// UintsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) +// to reduce it to a single value. +// @accumulator +// The accumulator accumulates callback's return values. +// It is the accumulated value previously returned in the last invocation of the callback—or initialValue, +// if it was supplied (see below). +// @initialValue +// A value to use as the first argument to the first call of the callback. +// If no initialValue is supplied, the first element in the slice will be used and skipped. +func UintsReduceRight(u []uint, + fn func(u []uint, k int, v, accumulator uint) uint, initialValue ...uint, +) uint { + if len(u) == 0 { + return 0 + } + end := len(u) - 1 + acc := u[end] + if len(initialValue) > 0 { + acc = initialValue[0] + } else { + end -= 1 + } + for k := end; k >= 0; k-- { + acc = fn(u, k, u[k], acc) + } + return acc +} + +// UintsReverse reverses an slice in place. +func UintsReverse(u []uint) { + first := 0 + last := len(u) - 1 + for first < last { + u[first], u[last] = u[last], u[first] + first++ + last-- + } +} + +// UintsShift removes the first element from an slice and returns that removed element. +// This method changes the length of the slice. +func UintsShift(u *[]uint) (uint, bool) { + a := *u + if len(a) == 0 { + return 0, false + } + first := a[0] + a = a[1:] + *u = a[:len(a):len(a)] + return first, true +} + +// UintsSlice returns a copy of a portion of an slice into a new slice object selected +// from begin to end (end not included) where begin and end represent the index of items in that slice. +// The original slice will not be modified. +func UintsSlice(u []uint, begin int, end ...int) []uint { + fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) + if !ok { + return []uint{} + } + return UintsCopy(u[fixedStart:fixedEnd]) +} + +// UintsSome tests whether at least one element in the slice passes the test implemented by the provided function. +// NOTE: +// Calling this method on an empty slice returns false for any condition! +func UintsSome(u []uint, fn func(u []uint, k int, v uint) bool) bool { + for k, v := range u { + if fn(u, k, v) { + return true + } + } + return false +} + +// UintsSplice changes the contents of an slice by removing or replacing +// existing elements and/or adding new elements in place. +func UintsSplice(u *[]uint, start, deleteCount int, items ...uint) { + a := *u + if deleteCount < 0 { + deleteCount = 0 + } + start, end, _ := fixRange(len(a), start, start+1+deleteCount) + deleteCount = end - start - 1 + for k := 0; k < len(items); k++ { + if deleteCount > 0 { + // replace + a[start] = items[k] + deleteCount-- + start++ + } else { + // insert + lastSlice := UintsCopy(a[start:]) + items = items[k:] + a = append(a[:start], items...) + a = append(a[:start+len(items)], lastSlice...) + *u = a[:len(a):len(a)] + return + } + } + if deleteCount > 0 { + a = append(a[:start], a[start+1+deleteCount:]...) + } + *u = a[:len(a):len(a)] +} + +// UintsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. +func UintsUnshift(u *[]uint, element ...uint) int { + *u = append(element, *u...) + return len(*u) +} + +// UintsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning +// and returns the new length of the slice. +func UintsUnshiftDistinct(u *[]uint, element ...uint) int { + a := *u + if len(element) == 0 { + return len(a) + } + m := make(map[uint]bool, len(element)) + r := make([]uint, 0, len(a)+len(element)) +L: + for _, v := range element { + if m[v] { + continue + } + m[v] = true + for _, vv := range a { + if vv == v { + continue L + } + } + r = append(r, v) + } + r = append(r, a...) + *u = r[:len(r):len(r)] + return len(r) +} + +// UintsRemoveFirst removes the first matched elements from the slice, +// and returns the new length of the slice. +func UintsRemoveFirst(p *[]uint, elements ...uint) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for k, v := range a { + if v == element { + a = append(a[:k], a[k+1:]...) + break + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// UintsRemoveEvery removes all the elements from the slice, +// and returns the new length of the slice. +func UintsRemoveEvery(p *[]uint, elements ...uint) int { + a := *p + m := make(map[interface{}]struct{}, len(elements)) + for _, element := range elements { + if _, ok := m[element]; ok { + continue + } + m[element] = struct{}{} + for i := 0; i < len(a); i++ { + if a[i] == element { + a = append(a[:i], a[i+1:]...) + i-- + } + } + } + n := len(a) + *p = a[:n:n] + return n +} + +// UintsConcat is used to merge two or more slices. +// This method does not change the existing slices, but instead returns a new slice. +func UintsConcat(u ...[]uint) []uint { + var totalLen int + for _, v := range u { + totalLen += len(v) + } + ret := make([]uint, totalLen) + dst := ret + for _, v := range u { + n := copy(dst, v) + dst = dst[n:] + } + return ret +} + +// UintsIntersect calculates intersection of two or more slices, +// and returns the count of each element. +func UintsIntersect(u ...[]uint) (intersectCount map[uint]int) { + if len(u) == 0 { + return nil + } + for _, v := range u { + if len(v) == 0 { + return nil + } + } + counts := make([]map[uint]int, len(u)) + for k, v := range u { + counts[k] = uintsDistinct(v, nil) + } + intersectCount = counts[0] +L: + for k, v := range intersectCount { + for _, c := range counts[1:] { + v2 := c[k] + if v2 == 0 { + delete(intersectCount, k) + continue L + } + if v > v2 { + v = v2 + } + } + intersectCount[k] = v + } + return intersectCount +} + +// UintsDistinct calculates the count of each different element, +// and only saves these different elements in place if changeSlice is true. +func UintsDistinct(i *[]uint, changeSlice bool) (distinctCount map[uint]int) { + if !changeSlice { + return uintsDistinct(*i, nil) + } + a := (*i)[:0] + distinctCount = uintsDistinct(*i, &a) + n := len(distinctCount) + *i = a[:n:n] + return distinctCount +} + +func uintsDistinct(src []uint, dst *[]uint) map[uint]int { + m := make(map[uint]int, len(src)) + if dst == nil { + for _, v := range src { + n := m[v] + m[v] = n + 1 + } + } else { + a := *dst + for _, v := range src { + n := m[v] + m[v] = n + 1 + if n == 0 { + a = append(a, v) + } + } + *dst = a + } + return m +} + +// UintSetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... +// This method does not change the existing slices, but instead returns a new slice. +func UintSetUnion(set1, set2 []uint, others ...[]uint) []uint { + m := make(map[uint]struct{}, len(set1)+len(set2)) + r := make([]uint, 0, len(m)) + for _, set := range append([][]uint{set1, set2}, others...) { + for _, v := range set { + _, ok := m[v] + if ok { + continue + } + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} + +// UintSetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... +// This method does not change the existing slices, but instead returns a new slice. +func UintSetIntersect(set1, set2 []uint, others ...[]uint) []uint { + sets := append([][]uint{set2}, others...) + setsCount := make([]map[uint]int, len(sets)) + for k, v := range sets { + setsCount[k] = uintsDistinct(v, nil) + } + m := make(map[uint]struct{}, len(set1)) + r := make([]uint, 0, len(m)) +L: + for _, v := range set1 { + if _, ok := m[v]; ok { + continue + } + m[v] = struct{}{} + for _, m2 := range setsCount { + if m2[v] == 0 { + continue L + } + } + r = append(r, v) + } + return r +} + +// UintSetDifference calculates between multiple collections: set1 - set2 - others... +// This method does not change the existing slices, but instead returns a new slice. +func UintSetDifference(set1, set2 []uint, others ...[]uint) []uint { + m := make(map[uint]struct{}, len(set1)) + r := make([]uint, 0, len(set1)) + sets := append([][]uint{set2}, others...) + for _, v := range sets { + inter := UintSetIntersect(set1, v) + for _, v := range inter { + m[v] = struct{}{} + } + } + for _, v := range set1 { + if _, ok := m[v]; !ok { + r = append(r, v) + m[v] = struct{}{} + } + } + return r +} diff --git a/vendor/github.com/henrylee2cn/ameda/utils.go b/vendor/github.com/henrylee2cn/ameda/utils.go new file mode 100644 index 0000000..546b440 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/utils.go @@ -0,0 +1,107 @@ +package ameda + +import ( + "errors" + "math" + "reflect" + "strconv" +) + +const ( + Host64bit = strconv.IntSize == 64 + Host32bit = ^uint(0)>>32 == 0 +) + +var ( + errNegativeValue = errors.New("contains negative value") + errOverflowValue = errors.New("contains overflow value") +) + +var ( + maxUint32 = uint32(math.MaxUint32) + maxInt64 = int64(math.MaxInt64) +) + +func isEmptyAsZero(emptyAsZero []bool) bool { + return len(emptyAsZero) > 0 && emptyAsZero[0] +} + +func getFromIndex(length int, fromIndex ...int) int { + if len(fromIndex) > 0 { + return fixIndex(length, fromIndex[0], true) + } + return 0 +} + +func fixRange(length, start int, end ...int) (fixedStart, fixedEnd int, ok bool) { + fixedStart = fixIndex(length, start, true) + if fixedStart == length { + return + } + fixedEnd = length + if len(end) > 0 { + fixedEnd = fixIndex(length, end[0], true) + } + if fixedEnd-fixedStart <= 0 { + return + } + ok = true + return +} + +func fixIndex(length int, idx int, canLen bool) int { + if idx < 0 { + idx = length + idx + if idx < 0 { + return 0 + } + return idx + } + if idx >= length { + if canLen { + return length + } + return length - 1 + } + return idx +} + +// isZero reports whether v is the zero value for its type. +// It panics if the argument is invalid. +func isZero(v reflect.Value) bool { + switch v.Kind() { + 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 math.Float64bits(v.Float()) == 0 + case reflect.Complex64, reflect.Complex128: + c := v.Complex() + return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 + case reflect.Array: + for i := 0; i < v.Len(); i++ { + if !isZero(v.Index(i)) { + return false + } + } + return true + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: + return v.IsNil() + case reflect.String: + return v.Len() == 0 + case reflect.Struct: + for i := 0; i < v.NumField(); i++ { + if !isZero(v.Field(i)) { + return false + } + } + return true + default: + // This should never happens, but will act as a safeguard for + // later, as a default value doesn't makes sense here. + panic(&reflect.ValueError{"reflect.Value.IsZero", v.Kind()}) + } +} diff --git a/vendor/github.com/henrylee2cn/ameda/value.go b/vendor/github.com/henrylee2cn/ameda/value.go new file mode 100644 index 0000000..6a6bcd3 --- /dev/null +++ b/vendor/github.com/henrylee2cn/ameda/value.go @@ -0,0 +1,301 @@ +package ameda + +import ( + "fmt" + "reflect" + "runtime" + "strings" + "unsafe" +) + +// Value go underlying type data +type Value struct { + flag + typPtr uintptr + ptr unsafe.Pointer + _iPtr unsafe.Pointer // avoid being GC +} + +// ValueOf unpacks i to go underlying type data. +func ValueOf(i interface{}) Value { + checkValueUsable() + return newT(unsafe.Pointer(&i)) +} + +// ValueFrom gets go underlying type data from reflect.Value. +func ValueFrom(v reflect.Value) Value { + return ValueFrom2(&v) +} + +// ValueFrom2 gets go underlying type data from *reflect.Value. +func ValueFrom2(v *reflect.Value) Value { + checkValueUsable() + vv := newT(unsafe.Pointer(v)) + if v.CanAddr() { + vv.flag |= flagAddr + } + return vv +} + +//go:nocheckptr +func newT(iPtr unsafe.Pointer) Value { + typPtr := *(*uintptr)(iPtr) + return Value{ + typPtr: typPtr, + flag: getFlag(typPtr), + ptr: pointerElem(unsafe.Pointer(uintptr(iPtr) + ptrOffset)), + _iPtr: iPtr, + } +} + +// RuntimeTypeIDOf returns the underlying type ID in current runtime from interface object. +// NOTE: +// *A and A returns the different runtime type ID; +// It is 10 times performance of t.String(). +//go:nocheckptr +func RuntimeTypeIDOf(i interface{}) uintptr { + checkValueUsable() + iPtr := unsafe.Pointer(&i) + typPtr := *(*uintptr)(iPtr) + return typPtr +} + +// RuntimeTypeID returns the underlying type ID in current runtime from reflect.Type. +// NOTE: +// *A and A returns the different runtime type ID; +// It is 10 times performance of t.String(). +//go:nocheckptr +func RuntimeTypeID(t reflect.Type) uintptr { + checkValueUsable() + typPtr := uintptrElem(uintptr(unsafe.Pointer(&t)) + ptrOffset) + return typPtr +} + +// RuntimeTypeID gets the underlying type ID in current runtime. +// NOTE: +// *A and A gets the different runtime type ID; +// It is 10 times performance of reflect.TypeOf(i).String(). +//go:nocheckptr +func (v Value) RuntimeTypeID() uintptr { + return v.typPtr +} + +// Kind gets the reflect.Kind fastly. +func (v Value) Kind() reflect.Kind { + return reflect.Kind(v.flag & flagKindMask) +} + +// CanAddr reports whether the value's address can be obtained with Addr. +// Such values are called addressable. A value is addressable if it is +// an element of a slice, an element of an addressable array, +// a field of an addressable struct, or the result of dereferencing a pointer. +func (v Value) CanAddr() bool { + return v.flag&flagAddr != 0 +} + +// Elem returns the Value that the interface i contains +// or that the pointer i points to. +//go:nocheckptr +func (v Value) Elem() Value { + k := v.Kind() + switch k { + default: + return v + case reflect.Interface: + return newT(v.ptr) + case reflect.Ptr: + flag2, typPtr2, has := typeUnderlying(v.flag, v.typPtr) + if has { + v.typPtr = typPtr2 + v.flag = flag2 + if v.Kind() == reflect.Ptr { + v.ptr = pointerElem(v.ptr) + } + } + return v + } +} + +// UnderlyingElem returns the underlying Value that the interface i contains +// or that the pointer i points to. +//go:nocheckptr +func (v Value) UnderlyingElem() Value { + for kind := v.Kind(); kind == reflect.Ptr || kind == reflect.Interface; kind = v.Kind() { + v = v.Elem() + } + return v +} + +// Pointer gets the pointer of i. +// NOTE: +// *T and T, gets diffrent pointer +//go:nocheckptr +func (v Value) Pointer() uintptr { + switch v.Kind() { + case reflect.Invalid: + return 0 + case reflect.Slice: + return uintptrElem(uintptr(v.ptr)) + sliceDataOffset + default: + return uintptr(v.ptr) + } +} + +// IsNil reports whether its argument i is nil. +//go:nocheckptr +func (v Value) IsNil() bool { + return unsafe.Pointer(v.Pointer()) == nil +} + +// FuncForPC returns a *Func describing the function that contains the +// given program counter address, or else nil. +// +// If pc represents multiple functions because of inlining, it returns +// the a *Func describing the innermost function, but with an entry +// of the outermost function. +// +// NOTE: Its kind must be a reflect.Func, otherwise it returns nil +//go:nocheckptr +func (v Value) FuncForPC() *runtime.Func { + return runtime.FuncForPC(*(*uintptr)(v.ptr)) +} + +//go:nocheckptr +func typeUnderlying(flagVal flag, typPtr uintptr) (flag, uintptr, bool) { + typPtr2 := uintptrElem(typPtr + elemOffset) + if unsafe.Pointer(typPtr2) == nil { + return flagVal, typPtr, false + } + tt := (*ptrType)(unsafe.Pointer(typPtr2)) + flagVal2 := flagVal&flagRO | flagIndir | flagAddr + flagVal2 |= flag(tt.kind) & flagKindMask + return flagVal2, typPtr2, true +} + +//go:nocheckptr +func getFlag(typPtr uintptr) flag { + if unsafe.Pointer(typPtr) == nil { + return 0 + } + return *(*flag)(unsafe.Pointer(typPtr + kindOffset)) +} + +//go:nocheckptr +func uintptrElem(ptr uintptr) uintptr { + return *(*uintptr)(unsafe.Pointer(ptr)) +} + +//go:nocheckptr +func pointerElem(p unsafe.Pointer) unsafe.Pointer { + return *(*unsafe.Pointer)(p) +} + +var errValueUsable error + +func init() { + if errValueUsable == nil { + _, errValueUsable = checkGoVersion(runtime.Version()) + } +} + +func checkGoVersion(goVer string) (string, error) { + var rs []rune + for _, r := range strings.TrimPrefix(goVer, "go") { + if r >= '0' && r <= '9' || r == '.' { + rs = append(rs, r) + } else { + break + } + } + goVersion := strings.TrimRight(string(rs), ".") + a, err := StringsToInts(strings.Split(goVersion, ".")) + if err != nil { + return goVersion, err + } + if a[0] != 1 || a[1] < 9 { + return goVersion, fmt.Errorf("required 1.9≤go<2.0, but current version is go" + goVersion) + } + return goVersion, nil +} + +func checkValueUsable() { + if errValueUsable != nil { + panic(errValueUsable) + } +} + +var ( + e = emptyInterface{typ: new(rtype)} + ptrOffset = func() uintptr { + return unsafe.Offsetof(e.word) + }() + kindOffset = func() uintptr { + return unsafe.Offsetof(e.typ.kind) + }() + elemOffset = func() uintptr { + return unsafe.Offsetof(new(ptrType).elem) + }() + sliceDataOffset = func() uintptr { + return unsafe.Offsetof(new(reflect.SliceHeader).Data) + }() + // valueFlagOffset = func() uintptr { + // t := reflect.TypeOf(reflect.Value{}) + // s, ok := t.FieldByName("flag") + // if !ok { + // errValueUsable = errors.New("not found reflect.Value.flag field") + // return 0 + // } + // return s.Offset + // }() +) + +// NOTE: The following definitions must be consistent with those in the standard package!!! + +const ( + flagKindWidth = 5 // there are 27 kinds + flagKindMask flag = 1< 0 { - block.Encrypt(dst, src) - src = src[bs:] - dst = dst[bs:] - } - dst = make([]byte, hex.EncodedLen(len(r))) - hex.Encode(dst, r) - return dst -} - -// AESDecrypt decrypts a piece of data. -// The cipherkey argument should be the AES key, -// either 16, 24, or 32 bytes to select -// AES-128, AES-192, or AES-256. -func AESDecrypt(cipherkey, ciphertext []byte) ([]byte, error) { - block, err := aes.NewCipher(cipherkey) - if err != nil { - return nil, err - } - src := make([]byte, hex.DecodedLen(len(ciphertext))) - _, err = hex.Decode(src, ciphertext) - if err != nil { - return nil, err - } - bs := block.BlockSize() - r := make([]byte, len(src)) - dst := r - for len(src) > 0 { - block.Decrypt(dst, src) - src = src[bs:] - dst = dst[bs:] - } - return removePad(r) -} - -func padData(d []byte, bs int) []byte { - padedSize := ((len(d) / bs) + 1) * bs - pad := padedSize - len(d) - for i := len(d); i < padedSize; i++ { - d = append(d, byte(pad)) - } - return d -} - -func removePad(r []byte) ([]byte, error) { - l := len(r) - if l == 0 { - return []byte{}, errors.New("input []byte is empty") - } - last := int(r[l-1]) - pad := r[l-last : l] - isPad := true - for _, v := range pad { - if int(v) != last { - isPad = false - break - } - } - if !isPad { - return r, errors.New("remove pad error") - } - return r[:l-last], nil -} diff --git a/vendor/github.com/henrylee2cn/goutil/go.mod b/vendor/github.com/henrylee2cn/goutil/go.mod deleted file mode 100644 index 4b4d5e2..0000000 --- a/vendor/github.com/henrylee2cn/goutil/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/henrylee2cn/goutil - -go 1.12 - -require github.com/stretchr/testify v1.4.0 diff --git a/vendor/github.com/henrylee2cn/goutil/go.sum b/vendor/github.com/henrylee2cn/goutil/go.sum deleted file mode 100644 index 68164f9..0000000 --- a/vendor/github.com/henrylee2cn/goutil/go.sum +++ /dev/null @@ -1,12 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/henrylee2cn/goutil/gotest.go b/vendor/github.com/henrylee2cn/goutil/gotest.go deleted file mode 100644 index d5b68ee..0000000 --- a/vendor/github.com/henrylee2cn/goutil/gotest.go +++ /dev/null @@ -1,31 +0,0 @@ -package goutil - -import ( - "flag" - "os" - "strings" -) - -// IsGoTest returns whether the current process is a test. -func IsGoTest() bool { - return isGoTest -} - -var isGoTest bool - -func init() { - isGoTest = checkGoTestEnv() -} - -func checkGoTestEnv() bool { - maybe := flag.Lookup("test.v") != nil || - flag.Lookup("test.run") != nil || - flag.Lookup("test.bench") != nil - if !maybe { - return false - } - if len(os.Args) == 0 { - return false - } - return strings.HasSuffix(os.Args[0], ".test") -} diff --git a/vendor/github.com/henrylee2cn/goutil/sets.go b/vendor/github.com/henrylee2cn/goutil/sets.go deleted file mode 100644 index 0e99d8e..0000000 --- a/vendor/github.com/henrylee2cn/goutil/sets.go +++ /dev/null @@ -1,479 +0,0 @@ -package goutil - -import "strconv" - -func isEmptyAsZero(emptyAsZero []bool) bool { - return len(emptyAsZero) > 0 && emptyAsZero[0] -} - -// StringsToBools converts string slice to bool slice. -func StringsToBools(a []string, emptyAsZero ...bool) ([]bool, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]bool, len(a)) - for k, v := range a { - i, err := strconv.ParseBool(v) - if err != nil && strict { - return nil, err - } - r[k] = i - } - return r, nil -} - -// StringsToFloat32s converts string slice to float32 slice. -func StringsToFloat32s(a []string, emptyAsZero ...bool) ([]float32, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]float32, len(a)) - for k, v := range a { - i, err := strconv.ParseFloat(v, 32) - if err != nil && strict { - return nil, err - } - r[k] = float32(i) - } - return r, nil -} - -// StringsToFloat64s converts string slice to float64 slice. -func StringsToFloat64s(a []string, emptyAsZero ...bool) ([]float64, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]float64, len(a)) - for k, v := range a { - i, err := strconv.ParseFloat(v, 64) - if err != nil && strict { - return nil, err - } - r[k] = i - } - return r, nil -} - -// StringsToInts converts string slice to int slice. -func StringsToInts(a []string, emptyAsZero ...bool) ([]int, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]int, len(a)) - for k, v := range a { - i, err := strconv.Atoi(v) - if err != nil && strict { - return nil, err - } - r[k] = i - } - return r, nil -} - -// StringsToInt64s converts string slice to int64 slice. -func StringsToInt64s(a []string, emptyAsZero ...bool) ([]int64, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]int64, len(a)) - for k, v := range a { - i, err := strconv.ParseInt(v, 10, 64) - if err != nil && strict { - return nil, err - } - r[k] = i - } - return r, nil -} - -// StringsToInt32s converts string slice to int32 slice. -func StringsToInt32s(a []string, emptyAsZero ...bool) ([]int32, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]int32, len(a)) - for k, v := range a { - i, err := strconv.ParseInt(v, 10, 32) - if err != nil && strict { - return nil, err - } - r[k] = int32(i) - } - return r, nil -} - -// StringsToInt16s converts string slice to int16 slice. -func StringsToInt16s(a []string, emptyAsZero ...bool) ([]int16, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]int16, len(a)) - for k, v := range a { - i, err := strconv.ParseInt(v, 10, 16) - if err != nil && strict { - return nil, err - } - r[k] = int16(i) - } - return r, nil -} - -// StringsToInt8s converts string slice to int8 slice. -func StringsToInt8s(a []string, emptyAsZero ...bool) ([]int8, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]int8, len(a)) - for k, v := range a { - i, err := strconv.ParseInt(v, 10, 8) - if err != nil && strict { - return nil, err - } - r[k] = int8(i) - } - return r, nil -} - -// StringsToUint8s converts string slice to uint8 slice. -func StringsToUint8s(a []string, emptyAsZero ...bool) ([]uint8, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]uint8, len(a)) - for k, v := range a { - i, err := strconv.ParseUint(v, 10, 8) - if err != nil && strict { - return nil, err - } - r[k] = uint8(i) - } - return r, nil -} - -// StringsToUint16s converts string slice to uint16 slice. -func StringsToUint16s(a []string, emptyAsZero ...bool) ([]uint16, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]uint16, len(a)) - for k, v := range a { - i, err := strconv.ParseUint(v, 10, 16) - if err != nil && strict { - return nil, err - } - r[k] = uint16(i) - } - return r, nil -} - -// StringsToUint32s converts string slice to uint32 slice. -func StringsToUint32s(a []string, emptyAsZero ...bool) ([]uint32, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]uint32, len(a)) - for k, v := range a { - i, err := strconv.ParseUint(v, 10, 32) - if err != nil && strict { - return nil, err - } - r[k] = uint32(i) - } - return r, nil -} - -// StringsToUint64s converts string slice to uint64 slice. -func StringsToUint64s(a []string, emptyAsZero ...bool) ([]uint64, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]uint64, len(a)) - for k, v := range a { - i, err := strconv.ParseUint(v, 10, 64) - if err != nil && strict { - return nil, err - } - r[k] = uint64(i) - } - return r, nil -} - -// StringsToUints converts string slice to uint slice. -func StringsToUints(a []string, emptyAsZero ...bool) ([]uint, error) { - strict := !isEmptyAsZero(emptyAsZero) - r := make([]uint, len(a)) - for k, v := range a { - i, err := strconv.ParseUint(v, 10, 64) - if err != nil && strict { - return nil, err - } - r[k] = uint(i) - } - return r, nil -} - -// StringsConvert converts the string slice to a new slice using fn. -// If fn returns error, exit the conversion and return the error. -func StringsConvert(a []string, fn func(string) (string, error)) ([]string, error) { - ret := make([]string, len(a)) - for i, s := range a { - r, err := fn(s) - if err != nil { - return nil, err - } - ret[i] = r - } - return ret, nil -} - -// StringsConvertMap converts the string slice to a new map using fn. -// If fn returns error, exit the conversion and return the error. -func StringsConvertMap(a []string, fn func(string) (string, error)) (map[string]string, error) { - ret := make(map[string]string, len(a)) - for _, s := range a { - r, err := fn(s) - if err != nil { - return nil, err - } - ret[s] = r - } - return ret, nil -} - -// IntersectStrings calculate intersection of two sets. -func IntersectStrings(set1, set2 []string) []string { - var intersect []string - var long, short = set1, set2 - if len(set1) < len(set2) { - long, short = set2, set1 - } - - buf := make([]string, len(short)) - copy(buf, short) - short = buf - - for _, m := range long { - if len(short) == 0 { - break - } - for j, n := range short { - if m == n { - intersect = append(intersect, n) - short = short[:j+copy(short[j:], short[j+1:])] - break - } - } - } - return intersect -} - -// StringsDistinct creates a string set that -// removes the same elements and returns them in their original order. -func StringsDistinct(a []string) (set []string) { - m := make(map[string]bool, len(a)) - set = make([]string, 0, len(a)) - for _, s := range a { - if m[s] { - continue - } - set = append(set, s) - m[s] = true - } - return set -} - -// SetToStrings sets a element to the string set. -func SetToStrings(set []string, a string) []string { - for _, s := range set { - if s == a { - return set - } - } - return append(set, a) -} - -// RemoveFromStrings removes the first element from the string set. -func RemoveFromStrings(set []string, a string) []string { - for i, s := range set { - if s == a { - return append(set[:i], set[i+1:]...) - } - } - return set -} - -// RemoveAllFromStrings removes all the a element from the string set. -func RemoveAllFromStrings(set []string, a string) []string { - length := len(set) - for { - set = RemoveFromStrings(set, a) - if length == len(set) { - return set - } - length = len(set) - } -} - -// IntsDistinct creates a int set that -// removes the same elements and returns them in their original order. -func IntsDistinct(a []int) (set []int) { - m := make(map[int]bool, len(a)) - set = make([]int, 0, len(a)) - for _, s := range a { - if m[s] { - continue - } - set = append(set, s) - m[s] = true - } - return set -} - -// SetToInts sets a element to the int set. -func SetToInts(set []int, a int) []int { - for _, s := range set { - if s == a { - return set - } - } - return append(set, a) -} - -// RemoveFromInts removes the first element from the int set. -func RemoveFromInts(set []int, a int) []int { - for i, s := range set { - if s == a { - return append(set[:i], set[i+1:]...) - } - } - return set -} - -// RemoveAllFromInts removes all the a element from the int set. -func RemoveAllFromInts(set []int, a int) []int { - length := len(set) - for { - set = RemoveFromInts(set, a) - if length == len(set) { - return set - } - length = len(set) - } -} - -// Int32sDistinct creates a int32 set that -// removes the same element32s and returns them in their original order. -func Int32sDistinct(a []int32) (set []int32) { - m := make(map[int32]bool, len(a)) - set = make([]int32, 0, len(a)) - for _, s := range a { - if m[s] { - continue - } - set = append(set, s) - m[s] = true - } - return set -} - -// SetToInt32s sets a element to the int32 set. -func SetToInt32s(set []int32, a int32) []int32 { - for _, s := range set { - if s == a { - return set - } - } - return append(set, a) -} - -// RemoveFromInt32s removes the first element from the int32 set. -func RemoveFromInt32s(set []int32, a int32) []int32 { - for i, s := range set { - if s == a { - return append(set[:i], set[i+1:]...) - } - } - return set -} - -// RemoveAllFromInt32s removes all the a element from the int32 set. -func RemoveAllFromInt32s(set []int32, a int32) []int32 { - length := len(set) - for { - set = RemoveFromInt32s(set, a) - if length == len(set) { - return set - } - length = len(set) - } -} - -// Int64sDistinct creates a int64 set that -// removes the same element64s and returns them in their original order. -func Int64sDistinct(a []int64) (set []int64) { - m := make(map[int64]bool, len(a)) - set = make([]int64, 0, len(a)) - for _, s := range a { - if m[s] { - continue - } - set = append(set, s) - m[s] = true - } - return set -} - -// SetToInt64s sets a element to the int64 set. -func SetToInt64s(set []int64, a int64) []int64 { - for _, s := range set { - if s == a { - return set - } - } - return append(set, a) -} - -// RemoveFromInt64s removes the first element from the int64 set. -func RemoveFromInt64s(set []int64, a int64) []int64 { - for i, s := range set { - if s == a { - return append(set[:i], set[i+1:]...) - } - } - return set -} - -// RemoveAllFromInt64s removes all the a element from the int64 set. -func RemoveAllFromInt64s(set []int64, a int64) []int64 { - length := len(set) - for { - set = RemoveFromInt64s(set, a) - if length == len(set) { - return set - } - length = len(set) - } -} - -// InterfacesDistinct creates a interface{} set that -// removes the same elementerface{}s and returns them in their original order. -func InterfacesDistinct(a []interface{}) (set []interface{}) { - m := make(map[interface{}]bool, len(a)) - set = make([]interface{}, 0, len(a)) - for _, s := range a { - if m[s] { - continue - } - set = append(set, s) - m[s] = true - } - return set -} - -// SetToInterfaces sets a element to the interface{} set. -func SetToInterfaces(set []interface{}, a interface{}) []interface{} { - for _, s := range set { - if s == a { - return set - } - } - return append(set, a) -} - -// RemoveFromInterfaces removes the first element from the interface{} set. -func RemoveFromInterfaces(set []interface{}, a interface{}) []interface{} { - for i, s := range set { - if s == a { - return append(set[:i], set[i+1:]...) - } - } - return set -} - -// RemoveAllFromInterfaces removes all the a element from the interface{} set. -func RemoveAllFromInterfaces(set []interface{}, a interface{}) []interface{} { - length := len(set) - for { - set = RemoveFromInterfaces(set, a) - if length == len(set) { - return set - } - length = len(set) - } -} diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go index a3a918f..ff7acf2 100644 --- a/vendor/golang.org/x/net/html/const.go +++ b/vendor/golang.org/x/net/html/const.go @@ -52,8 +52,7 @@ var isSpecialElementMap = map[string]bool{ "iframe": true, "img": true, "input": true, - "isindex": true, // The 'isindex' element has been removed, but keep it for backwards compatibility. - "keygen": true, + "keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility. "li": true, "link": true, "listing": true, diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go index 01477a9..9da9e9d 100644 --- a/vendor/golang.org/x/net/html/foreign.go +++ b/vendor/golang.org/x/net/html/foreign.go @@ -161,66 +161,62 @@ var mathMLAttributeAdjustments = map[string]string{ } var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan", } diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go index 633ee15..1350eef 100644 --- a/vendor/golang.org/x/net/html/node.go +++ b/vendor/golang.org/x/net/html/node.go @@ -18,6 +18,11 @@ const ( ElementNode CommentNode DoctypeNode + // RawNode nodes are not returned by the parser, but can be part of the + // Node tree passed to func Render to insert raw HTML (without escaping). + // If so, this package makes no guarantee that the rendered HTML is secure + // (from e.g. Cross Site Scripting attacks) or well-formed. + RawNode scopeMarkerNode ) diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 992cff2..038941d 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -184,6 +184,17 @@ func (p *parser) clearStackToContext(s scope) { } } +// parseGenericRawTextElements implements the generic raw text element parsing +// algorithm defined in 12.2.6.2. +// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text +// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part +// officially, need to make tokenizer consider both states. +func (p *parser) parseGenericRawTextElement() { + p.addElement() + p.originalIM = p.im + p.im = textIM +} + // generateImpliedEndTags pops nodes off the stack of open elements as long as // the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc. // If exceptions are specified, nodes with that name will not be popped off. @@ -192,16 +203,17 @@ func (p *parser) generateImpliedEndTags(exceptions ...string) { loop: for i = len(p.oe) - 1; i >= 0; i-- { n := p.oe[i] - if n.Type == ElementNode { - switch n.DataAtom { - case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc: - for _, except := range exceptions { - if n.Data == except { - break loop - } + if n.Type != ElementNode { + break + } + switch n.DataAtom { + case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc: + for _, except := range exceptions { + if n.Data == except { + break loop } - continue } + continue } break } @@ -369,8 +381,7 @@ findIdenticalElements: // Section 12.2.4.3. func (p *parser) clearActiveFormattingElements() { for { - n := p.afe.pop() - if len(p.afe) == 0 || n.Type == scopeMarkerNode { + if n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode { return } } @@ -625,29 +636,51 @@ func inHeadIM(p *parser) bool { switch p.tok.DataAtom { case a.Html: return inBodyIM(p) - case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: + case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta: p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() return true case a.Noscript: - p.addElement() if p.scripting { - p.setOriginalIM() - p.im = textIM - } else { - p.im = inHeadNoscriptIM + p.parseGenericRawTextElement() + return true } + p.addElement() + p.im = inHeadNoscriptIM + // Don't let the tokenizer go into raw text mode when scripting is disabled. + p.tokenizer.NextIsNotRawText() return true - case a.Script, a.Title, a.Noframes, a.Style: + case a.Script, a.Title: p.addElement() p.setOriginalIM() p.im = textIM return true + case a.Noframes, a.Style: + p.parseGenericRawTextElement() + return true case a.Head: // Ignore the token. return true case a.Template: + // TODO: remove this divergence from the HTML5 spec. + // + // We don't handle all of the corner cases when mixing foreign + // content (i.e. or ) with