Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/metaprogramming/primitiveConversions.hpp
40930 views
1
/*
2
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
26
#define SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
27
28
#include "memory/allStatic.hpp"
29
#include "metaprogramming/enableIf.hpp"
30
#include "utilities/globalDefinitions.hpp"
31
#include <type_traits>
32
33
class PrimitiveConversions : public AllStatic {
34
35
// True if types are the same size and either is integral.
36
template<typename To, typename From>
37
static constexpr bool check_cast() {
38
return (sizeof(To) == sizeof(From)) &&
39
(std::is_integral<To>::value || std::is_integral<From>::value);
40
}
41
42
public:
43
// template<typename To, typename From> To cast(From x)
44
//
45
// Return a value of type To with the same value representation as x.
46
//
47
// To and From must be of the same size.
48
//
49
// At least one of To or From must be an integral type. The other must
50
// be an integral, enum, floating point, or pointer type.
51
52
// integer -> integer
53
// Use static_cast for conversion. See C++14 4.7 Integral
54
// conversions. If To is signed and From unsigned, the result is
55
// implementation-defined. All supported platforms provide two's
56
// complement behavior, and that behavior is required by C++20.
57
// Using an lvalue to reference cast (see C++03 3.10/15) involves a
58
// reinterpret_cast, which prevents constexpr support.
59
template<typename To, typename From,
60
ENABLE_IF(sizeof(To) == sizeof(From)),
61
ENABLE_IF(std::is_integral<To>::value),
62
ENABLE_IF(std::is_integral<From>::value)>
63
static constexpr To cast(From x) {
64
return static_cast<To>(x);
65
}
66
67
// integer -> enum, enum -> integer
68
// Use the enum's underlying type for integer -> integer cast.
69
template<typename To, typename From,
70
ENABLE_IF(check_cast<To, From>()),
71
ENABLE_IF(std::is_enum<To>::value)>
72
static constexpr To cast(From x) {
73
return static_cast<To>(cast<std::underlying_type_t<To>>(x));
74
}
75
76
template<typename To, typename From,
77
ENABLE_IF(check_cast<To, From>()),
78
ENABLE_IF(std::is_enum<From>::value)>
79
static constexpr To cast(From x) {
80
return cast<To>(static_cast<std::underlying_type_t<From>>(x));
81
}
82
83
// integer -> pointer, pointer -> integer
84
// Use reinterpret_cast, so no constexpr support.
85
template<typename To, typename From,
86
ENABLE_IF(check_cast<To, From>()),
87
ENABLE_IF(std::is_pointer<To>::value || std::is_pointer<From>::value)>
88
static To cast(From x) {
89
return reinterpret_cast<To>(x);
90
}
91
92
// integer -> floating point, floating point -> integer
93
// Use the union trick. The union trick is technically UB, but is
94
// widely and well supported, producing good code. In some cases,
95
// such as gcc, that support is explicitly documented. Using memcpy
96
// is the correct method, but some compilers produce wretched code
97
// for that method, even at maximal optimization levels. Neither
98
// the union trick nor memcpy provides constexpr support.
99
template<typename To, typename From,
100
ENABLE_IF(check_cast<To, From>()),
101
ENABLE_IF(std::is_floating_point<To>::value ||
102
std::is_floating_point<From>::value)>
103
static To cast(From x) {
104
union { From from; To to; } converter = { x };
105
return converter.to;
106
}
107
108
// Support thin wrappers over primitive types.
109
// If derived from std::true_type, provides representational conversion
110
// from T to some other type. When true, must provide
111
// - Value: typedef for T.
112
// - Decayed: typedef for decayed type.
113
// - static Decayed decay(T x): return value of type Decayed with
114
// the same value representation as x.
115
// - static T recover(Decayed x): return a value of type T with the
116
// same value representation as x.
117
template<typename T> struct Translate : public std::false_type {};
118
};
119
120
// jfloat and jdouble translation to integral types
121
122
template<>
123
struct PrimitiveConversions::Translate<jdouble> : public std::true_type {
124
typedef double Value;
125
typedef int64_t Decayed;
126
127
static Decayed decay(Value x) { return PrimitiveConversions::cast<Decayed>(x); }
128
static Value recover(Decayed x) { return PrimitiveConversions::cast<Value>(x); }
129
};
130
131
template<>
132
struct PrimitiveConversions::Translate<jfloat> : public std::true_type {
133
typedef float Value;
134
typedef int32_t Decayed;
135
136
static Decayed decay(Value x) { return PrimitiveConversions::cast<Decayed>(x); }
137
static Value recover(Decayed x) { return PrimitiveConversions::cast<Value>(x); }
138
};
139
140
#endif // SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
141
142