1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 @file:Suppress("NOTHING_TO_INLINE")
18 
19 package androidx.compose.ui.util
20 
21 // These two functions are technically identical to Float.fromBits()
22 // and Double.fromBits(). However, since they are declared as top-
23 // level functions, they do not incur the cost of a static fetch
24 // through the Companion class. Using these top-level functions,
25 // the generated arm64 code after dex2oat is exactly a single `fmov`
26 
27 /** Returns the [Float] value corresponding to a given bit representation. */
floatFromBitsnull28 expect fun floatFromBits(bits: Int): Float
29 
30 /** Returns the [Double] value corresponding to a given bit representation. */
31 expect fun doubleFromBits(bits: Long): Double
32 
33 /**
34  * Returns the closest integer to the argument, tying rounding to positive infinity. Some values are
35  * treated differently:
36  * - NaN becomes 0
37  * - -Infinity or any value less than Integer.MIN_VALUE becomes Integer.MIN_VALUE.toFloat()
38  * - +Infinity or any value greater than Integer.MAX_VALUE becomes Integer.MAX_VALUE.toFloat()
39  */
40 expect fun Float.fastRoundToInt(): Int
41 
42 /**
43  * Returns the closest integer to the argument, tying rounding to positive infinity. Some values are
44  * treated differently:
45  * - NaN becomes 0
46  * - -Infinity or any value less than Integer.MIN_VALUE becomes Integer.MIN_VALUE.toFloat()
47  * - +Infinity or any value greater than Integer.MAX_VALUE becomes Integer.MAX_VALUE.toFloat()
48  */
49 expect fun Double.fastRoundToInt(): Int
50 
51 /** Packs two Float values into one Long value for use in inline classes. */
52 inline fun packFloats(val1: Float, val2: Float): Long {
53     val v1 = val1.toRawBits().toLong()
54     val v2 = val2.toRawBits().toLong()
55     return (v1 shl 32) or (v2 and 0xFFFFFFFF)
56 }
57 
58 /** Unpacks the first Float value in [packFloats] from its returned Long. */
unpackFloat1null59 inline fun unpackFloat1(value: Long): Float {
60     return floatFromBits((value shr 32).toInt())
61 }
62 
63 /** Unpacks the first absolute Float value in [packFloats] from its returned Long. */
unpackAbsFloat1null64 inline fun unpackAbsFloat1(value: Long): Float {
65     return floatFromBits(((value shr 32) and 0x7FFFFFFF).toInt())
66 }
67 
68 /** Unpacks the second Float value in [packFloats] from its returned Long. */
unpackFloat2null69 inline fun unpackFloat2(value: Long): Float {
70     return floatFromBits((value and 0xFFFFFFFF).toInt())
71 }
72 
73 /** Unpacks the second absolute Float value in [packFloats] from its returned Long. */
unpackAbsFloat2null74 inline fun unpackAbsFloat2(value: Long): Float {
75     return floatFromBits((value and 0x7FFFFFFF).toInt())
76 }
77 
78 /** Packs two Int values into one Long value for use in inline classes. */
packIntsnull79 inline fun packInts(val1: Int, val2: Int): Long {
80     return (val1.toLong() shl 32) or (val2.toLong() and 0xFFFFFFFF)
81 }
82 
83 /** Unpacks the first Int value in [packInts] from its returned ULong. */
unpackInt1null84 inline fun unpackInt1(value: Long): Int {
85     return (value shr 32).toInt()
86 }
87 
88 /** Unpacks the second Int value in [packInts] from its returned ULong. */
unpackInt2null89 inline fun unpackInt2(value: Long): Int {
90     return (value and 0xFFFFFFFF).toInt()
91 }
92