1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
Backport of https://github.com/fcitx/libime/commit/59ae4a3ab4becdab164f29af07c502096c745b94.diff
Backport upstream commit 59ae4a3 to fix the nanf value issue on musl
--- a/src/libime/core/datrie.cpp
+++ b/src/libime/core/datrie.cpp
@@ -47,12 +47,24 @@ struct NanValue {
static inline int32_t NO_PATH() { return -2; }
};
+// Musl doesn't have nanf implementation we need, just check if they are the
+// same value. If not, prefer old hardcoded value.
+bool isGoodNanf() {
+ int32_t noValue = decodeValue(std::nanf("1"));
+ int32_t noPath = decodeValue(std::nanf("2"));
+ return (noValue != noPath);
+}
+
template <>
struct NanValue<float> {
static_assert(std::numeric_limits<float>::has_quiet_NaN,
"Require support for quiet NaN.");
- static inline int32_t NO_VALUE() { return decodeValue(std::nanf("1")); }
- static inline int32_t NO_PATH() { return decodeValue(std::nanf("2")); }
+ static inline int32_t NO_VALUE() {
+ return isGoodNanf() ? decodeValue(std::nanf("1")) : 0x7fc00001;
+ }
+ static inline int32_t NO_PATH() {
+ return isGoodNanf() ? decodeValue(std::nanf("2")) : 0x7fc00002;
+ }
};
} // namespace
@@ -1144,6 +1156,20 @@ bool DATrie<T>::isValid(value_type v) {
return !(isNoPath(v) || isNoValue(v));
}
+template <typename T>
+T DATrie<T>::noPath() {
+ typename DATriePrivate<T>::decorder_type d;
+ d.result = DATriePrivate<value_type>::CEDAR_NO_PATH;
+ return d.result_value;
+}
+
+template <typename T>
+T DATrie<T>::noValue() {
+ typename DATriePrivate<T>::decorder_type d;
+ d.result = DATriePrivate<value_type>::CEDAR_NO_VALUE;
+ return d.result_value;
+}
+
template <typename T>
size_t DATrie<T>::mem_size() const {
// std::cout << "tail" << d->m_tail.size() << std::endl
--- a/src/libime/core/datrie.h
+++ b/src/libime/core/datrie.h
@@ -136,6 +136,9 @@ class DATrie {
static bool isNoPath(value_type v);
static bool isNoValue(value_type v);
+ static value_type noPath();
+ static value_type noValue();
+
size_t mem_size() const;
private:
--- a/test/testtrie.cpp
+++ b/test/testtrie.cpp
@@ -40,8 +40,8 @@ int main() {
FCITX_ASSERT(trie.size() == 4);
DATrie<float>::position_type pos = 0;
auto result = trie.traverse("aaa", pos);
- auto nan1 = std::nanf("1");
- auto nan2 = std::nanf("2");
+ auto nan1 = trie.noValue();
+ auto nan2 = trie.noPath();
// NaN != NaN, we must use memcmp to do this.
FCITX_ASSERT(memcmp(&nan1, &result, sizeof(float)) == 0);
FCITX_ASSERT(trie.isNoValue(result));
|