15d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/*
25d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Copyright (C) 2016 The Android Open Source Project
35d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
45d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
55d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * you may not use this file except in compliance with the License.
65d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * You may obtain a copy of the License at
75d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
85d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
95d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Unless required by applicable law or agreed to in writing, software
115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * See the License for the specific language governing permissions and
145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * limitations under the License.
155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */
165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
171d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#pragma once
185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <stdint.h>
205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <iosfwd>
215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <limits>
225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <type_traits>
235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
246e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa#ifndef LIKELY
2547df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#define LIKELY_DEFINED_LOCAL
265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#ifdef __cplusplus
275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#   define LIKELY( exp )    (__builtin_expect( !!(exp), true ))
285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#   define UNLIKELY( exp )  (__builtin_expect( !!(exp), false ))
295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#else
305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#   define LIKELY( exp )    (__builtin_expect( !!(exp), 1 ))
315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#   define UNLIKELY( exp )  (__builtin_expect( !!(exp), 0 ))
325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#endif
336e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa#endif
345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
35caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#if __cplusplus >= 201402L
36caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR constexpr
37caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#else
38caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR
39caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#endif
40caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy
415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace android {
425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/*
445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * half-float
455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *  1   5       10
475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * +-+------+------------+
485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * |s|eee.ee|mm.mmmm.mmmm|
495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * +-+------+------------+
505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * minimum (denormal) value: 2^-24 = 5.96e-8
525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * minimum (normal) value:   2^-14 = 6.10e-5
535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * maximum value:            2-2^-10 = 65504
545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy *
555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Integers between 0 and 2048 can be represented exactly
565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */
575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass half {
585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    struct fp16 {
594fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong        uint16_t bits;
604fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong        explicit constexpr fp16() noexcept : bits(0) { }
61caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        explicit constexpr fp16(uint16_t b) noexcept : bits(b) { }
625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setS(unsigned int s) noexcept { bits = uint16_t((bits & 0x7FFF) | (s<<15)); }
635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setE(unsigned int s) noexcept { bits = uint16_t((bits & 0xE3FF) | (s<<10)); }
645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setM(unsigned int s) noexcept { bits = uint16_t((bits & 0xFC00) | (s<< 0)); }
65caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getS() const noexcept { return  bits >> 15u; }
66caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getE() const noexcept { return (bits >> 10u) & 0x1Fu; }
67caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getM() const noexcept { return  bits         & 0x3FFu; }
685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    };
695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    struct fp32 {
705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        union {
714fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong            uint32_t bits;
725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            float fp;
735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        };
744fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong        explicit constexpr fp32() noexcept : bits(0) { }
754fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong        explicit constexpr fp32(float f) noexcept : fp(f) { }
765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setS(unsigned int s) noexcept { bits = uint32_t((bits & 0x7FFFFFFF) | (s<<31)); }
775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setE(unsigned int s) noexcept { bits = uint32_t((bits & 0x807FFFFF) | (s<<23)); }
785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        void setM(unsigned int s) noexcept { bits = uint32_t((bits & 0xFF800000) | (s<< 0)); }
79caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getS() const noexcept { return  bits >> 31u; }
80caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getE() const noexcept { return (bits >> 23u) & 0xFFu; }
81caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        constexpr unsigned int getM() const noexcept { return  bits         & 0x7FFFFFu; }
825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    };
835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic:
85caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    CONSTEXPR half(float v) noexcept : mBits(ftoh(v)) { }
86caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    CONSTEXPR operator float() const noexcept { return htof(mBits); }
875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    uint16_t getBits() const noexcept { return mBits.bits; }
895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    unsigned int getExponent() const noexcept { return mBits.getE(); }
905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    unsigned int getMantissa() const noexcept { return mBits.getM(); }
915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyprivate:
935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    friend class std::numeric_limits<half>;
94caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    friend CONSTEXPR half operator"" _hf(long double v);
955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    enum Binary { binary };
975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    explicit constexpr half(Binary, uint16_t bits) noexcept : mBits(bits) { }
98caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    static CONSTEXPR fp16 ftoh(float v) noexcept;
99caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    static CONSTEXPR float htof(fp16 v) noexcept;
1005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    fp16 mBits;
1015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy};
1025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
103caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR half::fp16 half::ftoh(float v) noexcept {
1045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    fp16 out;
1055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    fp32 in(v);
1065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    if (UNLIKELY(in.getE() == 0xFF)) { // inf or nan
1075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        out.setE(0x1F);
1085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        out.setM(in.getM() ? 0x200 : 0);
1095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    } else {
110caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy        int e = static_cast<int>(in.getE()) - 127 + 15;
1115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        if (e >= 0x1F) {
1125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            // overflow
1135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            out.setE(0x31); // +/- inf
1145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        } else if (e <= 0) {
1155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            // underflow
1165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            // flush to +/- 0
1175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        } else {
1185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            unsigned int m = in.getM();
1195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            out.setE(uint16_t(e));
1205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            out.setM(m >> 13);
1215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            if (m & 0x1000) {
1225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy                // rounding
1235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy                out.bits++;
1245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            }
1255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        }
1265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    }
1275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    out.setS(in.getS());
1285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    return out;
1295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}
1305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
131caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR float half::htof(half::fp16 in) noexcept {
1325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    fp32 out;
1335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    if (UNLIKELY(in.getE() == 0x1F)) { // inf or nan
1345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        out.setE(0xFF);
1355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        out.setM(in.getM() ? 0x400000 : 0);
1365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    } else {
1375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        if (in.getE() == 0) {
1385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            if (in.getM()) {
1395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy                // TODO: denormal half float, treat as zero for now
1405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy                // (it's stupid because they can be represented as regular float)
1415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            }
1425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        } else {
143caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy            int e = static_cast<int>(in.getE()) - 15 + 127;
1445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            unsigned int m = in.getM();
1455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            out.setE(uint32_t(e));
1465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy            out.setM(m << 13);
1475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy        }
1485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    }
1495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    out.setS(in.getS());
1505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    return out.fp;
1515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}
1525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
153caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR android::half operator"" _hf(long double v) {
154caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy    return android::half(android::half::binary, android::half::ftoh(static_cast<float>(v)).bits);
1555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}
1565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace android
1585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace std {
1605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<> struct is_floating_point<android::half> : public std::true_type {};
1625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<>
1645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass numeric_limits<android::half> {
1655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic:
1665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    typedef android::half type;
1675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_specialized = true;
1695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_signed = true;
1705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_integer = false;
1715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_exact = false;
1725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool has_infinity = true;
1735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool has_quiet_NaN = true;
1745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool has_signaling_NaN = false;
1755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const float_denorm_style has_denorm = denorm_absent;
1765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool has_denorm_loss = true;
1775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_iec559 = false;
1785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_bounded = true;
1795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool is_modulo = false;
1805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool traps = false;
1815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const bool tinyness_before = false;
1825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const float_round_style round_style = round_indeterminate;
1835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int digits = 11;
1855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int digits10 = 3;
1865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int max_digits10 = 5;
1875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int radix = 2;
1885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int min_exponent = -13;
1895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int min_exponent10 = -4;
1905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int max_exponent = 16;
1915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    static constexpr const int max_exponent10 = 4;
1925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
1935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type round_error() noexcept { return android::half(android::half::binary, 0x3800); }
1945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type min() noexcept { return android::half(android::half::binary, 0x0400); }
1955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type max() noexcept { return android::half(android::half::binary, 0x7bff); }
1965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type lowest() noexcept { return android::half(android::half::binary, 0xfbff); }
1975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type epsilon() noexcept { return android::half(android::half::binary, 0x1400); }
1985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type infinity() noexcept { return android::half(android::half::binary, 0x7c00); }
1995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type quiet_NaN() noexcept { return android::half(android::half::binary, 0x7fff); }
2005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type denorm_min() noexcept { return android::half(android::half::binary, 0x0001); }
2015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy    inline static constexpr type signaling_NaN() noexcept { return android::half(android::half::binary, 0x7dff); }
2025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy};
2035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
2045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace std
2055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy
20647df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#ifdef LIKELY_DEFINED_LOCAL
20747df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#undef LIKELY_DEFINED_LOCAL
2085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef LIKELY
2095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef UNLIKELY
21047df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#endif // LIKELY_DEFINED_LOCAL
21147df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee
212caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#undef CONSTEXPR
213