1//  Copieright (c) 2014 Couchbase, Inc.
2//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3//  except in compliance with the License. You may obtain a copy of the License at
4//    http://www.apache.org/licenses/LICENSE-2.0
5//  Unless required by applicable law or agreed to in writing, software distributed under the
6//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
7//  either express or implied. See the License for the specific language governing permissions
8//  and limitations under the License.
9
10package value
11
12import (
13	"io"
14	"math"
15	"strconv"
16
17	"github.com/couchbase/query/util"
18)
19
20type floatValue float64
21
22var _NAN_BYTES = []byte("\"NaN\"")
23var _POS_INF_BYTES = []byte("\"+Infinity\"")
24var _NEG_INF_BYTES = []byte("\"-Infinity\"")
25
26func (this floatValue) String() string {
27	bytes, _ := this.MarshalJSON()
28	return string(bytes)
29}
30
31func (this floatValue) MarshalJSON() ([]byte, error) {
32	f := float64(this)
33
34	if math.IsNaN(f) {
35		return _NAN_BYTES, nil
36	} else if math.IsInf(f, 1) {
37		return _POS_INF_BYTES, nil
38	} else if math.IsInf(f, -1) {
39		return _NEG_INF_BYTES, nil
40	} else {
41		if f == -0 {
42			f = 0
43		}
44
45		s := strconv.FormatFloat(f, 'f', -1, 64)
46		return []byte(s), nil
47	}
48}
49
50func (this floatValue) WriteJSON(w io.Writer, prefix, indent string) error {
51	b, err := this.MarshalJSON()
52	if err != nil {
53		return err
54	}
55	_, err = w.Write(b)
56	return err
57}
58
59/*
60Type Number
61*/
62func (this floatValue) Type() Type {
63	return NUMBER
64}
65
66func (this floatValue) Actual() interface{} {
67	return float64(this)
68}
69
70func (this floatValue) ActualForIndex() interface{} {
71	return float64(this)
72}
73
74func (this floatValue) Equals(other Value) Value {
75	other = other.unwrap()
76	switch other := other.(type) {
77	case missingValue:
78		return other
79	case *nullValue:
80		return other
81	case floatValue:
82		if this == other {
83			return TRUE_VALUE
84		}
85	case intValue:
86		if float64(this) == float64(other) {
87			return TRUE_VALUE
88		}
89	}
90
91	return FALSE_VALUE
92}
93
94func (this floatValue) EquivalentTo(other Value) bool {
95	other = other.unwrap()
96	switch other := other.(type) {
97	case floatValue:
98		return this == other
99	case intValue:
100		return float64(this) == float64(other)
101	default:
102		return false
103	}
104}
105
106func (this floatValue) Collate(other Value) int {
107	other = other.unwrap()
108	switch other := other.(type) {
109	case floatValue:
110		t := float64(this)
111		o := float64(other)
112		return collateFloat(t, o)
113	case intValue:
114		t := float64(this)
115		o := float64(other)
116		return collateFloat(t, o)
117	default:
118		return int(NUMBER - other.Type())
119	}
120
121}
122
123func collateFloat(t, o float64) int {
124	// NaN sorts first
125	if math.IsNaN(t) {
126		if math.IsNaN(o) {
127			return 0
128		} else {
129			return -1
130		}
131	}
132
133	if math.IsNaN(o) {
134		return 1
135	}
136
137	// NegInfinity sorts next
138	if math.IsInf(t, -1) {
139		if math.IsInf(o, -1) {
140			return 0
141		} else {
142			return -1
143		}
144	}
145
146	if math.IsInf(o, -1) {
147		return 1
148	}
149
150	// PosInfinity sorts last
151	if math.IsInf(t, 1) {
152		if math.IsInf(o, 1) {
153			return 0
154		} else {
155			return 1
156		}
157	}
158
159	if math.IsInf(o, 1) {
160		return -1
161	}
162
163	result := t - o
164	switch {
165	case result < 0.0:
166		return -1
167	case result > 0.0:
168		return 1
169	default:
170		return 0
171	}
172}
173
174func (this floatValue) Compare(other Value) Value {
175	other = other.unwrap()
176	switch other := other.(type) {
177	case missingValue:
178		return other
179	case *nullValue:
180		return other
181	default:
182		return intValue(this.Collate(other))
183	}
184}
185
186/*
187Returns true in the event the receiver is not 0 and it isn’t
188a NaN value
189*/
190func (this floatValue) Truth() bool {
191	return !math.IsNaN(float64(this)) && this != 0
192}
193
194/*
195Return receiver
196*/
197func (this floatValue) Copy() Value {
198	return this
199}
200
201/*
202Return receiver
203*/
204func (this floatValue) CopyForUpdate() Value {
205	return this
206}
207
208/*
209Calls missingField.
210*/
211func (this floatValue) Field(field string) (Value, bool) {
212	return missingField(field), false
213}
214
215/*
216Not valid for NUMBER.
217*/
218func (this floatValue) SetField(field string, val interface{}) error {
219	return Unsettable(field)
220}
221
222/*
223Not valid for NUMBER.
224*/
225func (this floatValue) UnsetField(field string) error {
226	return Unsettable(field)
227}
228
229/*
230Calls missingIndex.
231*/
232func (this floatValue) Index(index int) (Value, bool) {
233	return missingIndex(index), false
234}
235
236/*
237Not valid for NUMBER.
238*/
239func (this floatValue) SetIndex(index int, val interface{}) error {
240	return Unsettable(index)
241}
242
243/*
244Returns NULL_VALUE
245*/
246func (this floatValue) Slice(start, end int) (Value, bool) {
247	return NULL_VALUE, false
248}
249
250/*
251Returns NULL_VALUE
252*/
253func (this floatValue) SliceTail(start int) (Value, bool) {
254	return NULL_VALUE, false
255}
256
257/*
258Returns the input buffer as is.
259*/
260func (this floatValue) Descendants(buffer []interface{}) []interface{} {
261	return buffer
262}
263
264/*
265As number has no fields, return nil.
266*/
267func (this floatValue) Fields() map[string]interface{} {
268	return nil
269}
270
271func (this floatValue) FieldNames(buffer []string) []string {
272	return nil
273}
274
275/*
276Returns the input buffer as is.
277*/
278func (this floatValue) DescendantPairs(buffer []util.IPair) []util.IPair {
279	return buffer
280}
281
282/*
283Obey N1QL collation order for numbers. After that, NUMBER is succeeded
284by STRING.
285*/
286func (this floatValue) Successor() Value {
287	// NaN sorts lowest
288	t := float64(this)
289
290	if math.IsNaN(t) {
291		return floatValue(math.Inf(-1))
292	}
293
294	// -Inf sorts next
295	if math.IsInf(t, -1) {
296		return floatValue(-math.MaxFloat64)
297	}
298
299	// +Inf sorts last
300	if math.IsInf(t, 1) || this >= math.MaxFloat64 {
301		return EMPTY_STRING_VALUE
302	}
303
304	return floatValue(math.Nextafter(t, math.MaxFloat64))
305}
306
307func (this floatValue) Recycle() {
308}
309
310func (this floatValue) Tokens(set *Set, options Value) *Set {
311	set.Add(this)
312	return set
313}
314
315func (this floatValue) ContainsToken(token, options Value) bool {
316	return this.EquivalentTo(token)
317}
318
319func (this floatValue) ContainsMatchingToken(matcher MatchFunc, options Value) bool {
320	return matcher(float64(this))
321}
322
323func (this floatValue) unwrap() Value {
324	return this
325}
326
327/*
328NumberValue methods.
329*/
330
331func (this floatValue) Add(n NumberValue) NumberValue {
332	return floatValue(float64(this) + n.Actual().(float64))
333}
334
335func (this floatValue) IDiv(n NumberValue) Value {
336	switch n := n.(type) {
337	case intValue:
338		if n == 0 {
339			return NULL_VALUE
340		} else {
341			return intValue(this) / n
342		}
343	default:
344		f := n.Actual().(float64)
345		if f == 0.0 {
346			return NULL_VALUE
347		} else {
348			return intValue(int64(this) / int64(f))
349		}
350	}
351}
352
353func (this floatValue) IMod(n NumberValue) Value {
354	switch n := n.(type) {
355	case intValue:
356		if n == 0 {
357			return NULL_VALUE
358		} else {
359			return intValue(this) % n
360		}
361	default:
362		f := n.Actual().(float64)
363		if f == 0.0 {
364			return NULL_VALUE
365		} else {
366			return intValue(int64(this) % int64(f))
367		}
368	}
369}
370
371func (this floatValue) Mult(n NumberValue) NumberValue {
372	return floatValue(float64(this) * n.Actual().(float64))
373}
374
375func (this floatValue) Neg() NumberValue {
376	return -this
377}
378
379func (this floatValue) Sub(n NumberValue) NumberValue {
380	return floatValue(float64(this) - n.Actual().(float64))
381}
382
383func (this floatValue) Int64() int64 {
384	return int64(this)
385}
386