Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tpl/math
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-07-06 15:12:10 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-07-06 18:51:38 +0300
commit2b8d907ab731627f4e2a30442cd729064516c8bb (patch)
tree2f9235dfbcf116c463b75d59c8be1be53d55b05a /tpl/math
parent43338c3a99769eb7d0df0c12559b8b3d42b67dba (diff)
Add a newScratch template func
Fixes #4685
Diffstat (limited to 'tpl/math')
-rw-r--r--tpl/math/math.go127
-rw-r--r--tpl/math/math_test.go87
2 files changed, 6 insertions, 208 deletions
diff --git a/tpl/math/math.go b/tpl/math/math.go
index 534f7f284..fcc6abc3d 100644
--- a/tpl/math/math.go
+++ b/tpl/math/math.go
@@ -16,7 +16,8 @@ package math
import (
"errors"
"math"
- "reflect"
+
+ _math "github.com/gohugoio/hugo/common/math"
"github.com/spf13/cast"
)
@@ -31,7 +32,7 @@ type Namespace struct{}
// Add adds two numbers.
func (ns *Namespace) Add(a, b interface{}) (interface{}, error) {
- return DoArithmetic(a, b, '+')
+ return _math.DoArithmetic(a, b, '+')
}
// Ceil returns the least integer value greater than or equal to x.
@@ -46,7 +47,7 @@ func (ns *Namespace) Ceil(x interface{}) (float64, error) {
// Div divides two numbers.
func (ns *Namespace) Div(a, b interface{}) (interface{}, error) {
- return DoArithmetic(a, b, '/')
+ return _math.DoArithmetic(a, b, '/')
}
// Floor returns the greatest integer value less than or equal to x.
@@ -98,7 +99,7 @@ func (ns *Namespace) ModBool(a, b interface{}) (bool, error) {
// Mul multiplies two numbers.
func (ns *Namespace) Mul(a, b interface{}) (interface{}, error) {
- return DoArithmetic(a, b, '*')
+ return _math.DoArithmetic(a, b, '*')
}
// Round returns the nearest integer, rounding half away from zero.
@@ -113,121 +114,5 @@ func (ns *Namespace) Round(x interface{}) (float64, error) {
// Sub subtracts two numbers.
func (ns *Namespace) Sub(a, b interface{}) (interface{}, error) {
- return DoArithmetic(a, b, '-')
-}
-
-// DoArithmetic performs arithmetic operations (+,-,*,/) using reflection to
-// determine the type of the two terms.
-func DoArithmetic(a, b interface{}, op rune) (interface{}, error) {
- av := reflect.ValueOf(a)
- bv := reflect.ValueOf(b)
- var ai, bi int64
- var af, bf float64
- var au, bu uint64
- switch av.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- ai = av.Int()
- switch bv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bi = bv.Int()
- case reflect.Float32, reflect.Float64:
- af = float64(ai) // may overflow
- ai = 0
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bu = bv.Uint()
- if ai >= 0 {
- au = uint64(ai)
- ai = 0
- } else {
- bi = int64(bu) // may overflow
- bu = 0
- }
- default:
- return nil, errors.New("Can't apply the operator to the values")
- }
- case reflect.Float32, reflect.Float64:
- af = av.Float()
- switch bv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bf = float64(bv.Int()) // may overflow
- case reflect.Float32, reflect.Float64:
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bf = float64(bv.Uint()) // may overflow
- default:
- return nil, errors.New("Can't apply the operator to the values")
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- au = av.Uint()
- switch bv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bi = bv.Int()
- if bi >= 0 {
- bu = uint64(bi)
- bi = 0
- } else {
- ai = int64(au) // may overflow
- au = 0
- }
- case reflect.Float32, reflect.Float64:
- af = float64(au) // may overflow
- au = 0
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bu = bv.Uint()
- default:
- return nil, errors.New("Can't apply the operator to the values")
- }
- case reflect.String:
- as := av.String()
- if bv.Kind() == reflect.String && op == '+' {
- bs := bv.String()
- return as + bs, nil
- }
- return nil, errors.New("Can't apply the operator to the values")
- default:
- return nil, errors.New("Can't apply the operator to the values")
- }
-
- switch op {
- case '+':
- if ai != 0 || bi != 0 {
- return ai + bi, nil
- } else if af != 0 || bf != 0 {
- return af + bf, nil
- } else if au != 0 || bu != 0 {
- return au + bu, nil
- }
- return 0, nil
- case '-':
- if ai != 0 || bi != 0 {
- return ai - bi, nil
- } else if af != 0 || bf != 0 {
- return af - bf, nil
- } else if au != 0 || bu != 0 {
- return au - bu, nil
- }
- return 0, nil
- case '*':
- if ai != 0 || bi != 0 {
- return ai * bi, nil
- } else if af != 0 || bf != 0 {
- return af * bf, nil
- } else if au != 0 || bu != 0 {
- return au * bu, nil
- }
- return 0, nil
- case '/':
- if bi != 0 {
- return ai / bi, nil
- } else if bf != 0 {
- return af / bf, nil
- } else if bu != 0 {
- return au / bu, nil
- }
- return nil, errors.New("Can't divide the value by 0")
- default:
- return nil, errors.New("There is no such an operation")
- }
+ return _math.DoArithmetic(a, b, '-')
}
diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go
index 97acfaeba..f2e6236af 100644
--- a/tpl/math/math_test.go
+++ b/tpl/math/math_test.go
@@ -56,93 +56,6 @@ func TestBasicNSArithmetic(t *testing.T) {
}
}
-func TestDoArithmetic(t *testing.T) {
- t.Parallel()
-
- for i, test := range []struct {
- a interface{}
- b interface{}
- op rune
- expect interface{}
- }{
- {3, 2, '+', int64(5)},
- {3, 2, '-', int64(1)},
- {3, 2, '*', int64(6)},
- {3, 2, '/', int64(1)},
- {3.0, 2, '+', float64(5)},
- {3.0, 2, '-', float64(1)},
- {3.0, 2, '*', float64(6)},
- {3.0, 2, '/', float64(1.5)},
- {3, 2.0, '+', float64(5)},
- {3, 2.0, '-', float64(1)},
- {3, 2.0, '*', float64(6)},
- {3, 2.0, '/', float64(1.5)},
- {3.0, 2.0, '+', float64(5)},
- {3.0, 2.0, '-', float64(1)},
- {3.0, 2.0, '*', float64(6)},
- {3.0, 2.0, '/', float64(1.5)},
- {uint(3), uint(2), '+', uint64(5)},
- {uint(3), uint(2), '-', uint64(1)},
- {uint(3), uint(2), '*', uint64(6)},
- {uint(3), uint(2), '/', uint64(1)},
- {uint(3), 2, '+', uint64(5)},
- {uint(3), 2, '-', uint64(1)},
- {uint(3), 2, '*', uint64(6)},
- {uint(3), 2, '/', uint64(1)},
- {3, uint(2), '+', uint64(5)},
- {3, uint(2), '-', uint64(1)},
- {3, uint(2), '*', uint64(6)},
- {3, uint(2), '/', uint64(1)},
- {uint(3), -2, '+', int64(1)},
- {uint(3), -2, '-', int64(5)},
- {uint(3), -2, '*', int64(-6)},
- {uint(3), -2, '/', int64(-1)},
- {-3, uint(2), '+', int64(-1)},
- {-3, uint(2), '-', int64(-5)},
- {-3, uint(2), '*', int64(-6)},
- {-3, uint(2), '/', int64(-1)},
- {uint(3), 2.0, '+', float64(5)},
- {uint(3), 2.0, '-', float64(1)},
- {uint(3), 2.0, '*', float64(6)},
- {uint(3), 2.0, '/', float64(1.5)},
- {3.0, uint(2), '+', float64(5)},
- {3.0, uint(2), '-', float64(1)},
- {3.0, uint(2), '*', float64(6)},
- {3.0, uint(2), '/', float64(1.5)},
- {0, 0, '+', 0},
- {0, 0, '-', 0},
- {0, 0, '*', 0},
- {"foo", "bar", '+', "foobar"},
- {3, 0, '/', false},
- {3.0, 0, '/', false},
- {3, 0.0, '/', false},
- {uint(3), uint(0), '/', false},
- {3, uint(0), '/', false},
- {-3, uint(0), '/', false},
- {uint(3), 0, '/', false},
- {3.0, uint(0), '/', false},
- {uint(3), 0.0, '/', false},
- {3, "foo", '+', false},
- {3.0, "foo", '+', false},
- {uint(3), "foo", '+', false},
- {"foo", 3, '+', false},
- {"foo", "bar", '-', false},
- {3, 2, '%', false},
- } {
- errMsg := fmt.Sprintf("[%d] %v", i, test)
-
- result, err := DoArithmetic(test.a, test.b, test.op)
-
- if b, ok := test.expect.(bool); ok && !b {
- require.Error(t, err, errMsg)
- continue
- }
-
- require.NoError(t, err, errMsg)
- assert.Equal(t, test.expect, result, errMsg)
- }
-}
-
func TestCeil(t *testing.T) {
t.Parallel()