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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Open Chinese Convert
*
* Copyright 2010-2020 Carbo Kuo <byvoid@byvoid.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <list>
#include <string_view>
#include "Common.hpp"
#include "DictEntry.hpp"
namespace opencc {
/**
* Defines how a dictionary group resolves matches across child dictionaries.
*/
enum class DictGroupMatchPolicy {
/**
* Preserve legacy DictGroup behavior: query child dictionaries in order and
* return the first dictionary that has a match. For prefix lookup, this means
* a shorter prefix from an earlier dictionary can win over a longer prefix
* from a later dictionary.
*/
ShortCircuit,
/**
* Treat child dictionaries as a union for prefix lookup: the longest prefix
* across all children wins, with dictionary order breaking ties.
*/
Union,
};
/**
* Result of a PrefixMatch fast-path lookup.
* key and value are non-owning views; see PrefixMatch::MatchPrefixView()
* for lifetime details.
*/
struct OPENCC_EXPORT PrefixMatchView {
bool matched = false;
size_t keyLength = 0;
std::string_view key;
std::string_view value;
};
/**
* Abstract class of dictionary
* @ingroup opencc_cpp_api
*/
class OPENCC_EXPORT Dict {
public:
/**
* Matches a word exactly and returns the DictEntry or Optional::Null().
*/
virtual Optional<const DictEntry*> Match(const char* word,
size_t len) const = 0;
/**
* Matches a word exactly and returns the DictEntry or Optional::Null().
*/
Optional<const DictEntry*> Match(const std::string& word) const {
return Match(word.c_str(), word.length());
}
/**
* Matches the longest matched prefix of a word.
* For example given a dictionary having "a", "an", "b", "ba", "ban", "bana",
* the longest prefix of "banana" matched is "bana".
*/
virtual Optional<const DictEntry*> MatchPrefix(const char* word,
size_t len) const;
/**
* Matches the longest matched prefix of a word.
*/
Optional<const DictEntry*> MatchPrefix(const char* word) const {
return MatchPrefix(word, KeyMaxLength());
}
/**
* Matches the longest matched prefix of a word.
*/
Optional<const DictEntry*> MatchPrefix(const std::string& word) const {
return MatchPrefix(word.c_str(), word.length());
}
/**
* Returns all matched prefixes of a word, sorted by the length (desc).
* For example given a dictionary having "a", "an", "b", "ba", "ban", "bana",
* all the matched prefixes of "banana" are "bana", "ban", "ba", "b".
*/
virtual std::vector<const DictEntry*> MatchAllPrefixes(const char* word,
size_t len) const;
/**
* Returns all matched prefixes of a word, sorted by the length (desc).
*/
std::vector<const DictEntry*>
MatchAllPrefixes(const std::string& word) const {
return MatchAllPrefixes(word.c_str(), word.length());
}
/**
* Returns the length of the longest key in the dictionary.
*/
virtual size_t KeyMaxLength() const = 0;
/**
* Returns all entries in the dictionary.
*/
virtual LexiconPtr GetLexicon() const = 0;
/**
* Returns child dictionaries when this dictionary is a group.
*/
virtual const std::list<DictPtr>* GetDictGroupItems() const {
return nullptr;
}
/**
* Returns the match policy when this dictionary is a group. Non-group
* dictionaries return ShortCircuit because the value is ignored unless
* GetDictGroupItems() returns children.
*/
virtual DictGroupMatchPolicy GetMatchPolicy() const {
return DictGroupMatchPolicy::ShortCircuit;
}
/**
* Returns true if this dict can handle prefix queries directly without
* PrefixMatch building a lookup table. Subclasses that override
* MatchPrefixValue() must also override this to return true.
*/
virtual bool SupportsFastPrefixMatch() const { return false; }
/**
* Fast-path prefix match. Only called when SupportsFastPrefixMatch() is
* true. Returns a PrefixMatchView with matched=false on no match.
* See PrefixMatch::MatchPrefixView() for key/value lifetime details.
*/
virtual PrefixMatchView MatchPrefixValue(const char* word,
size_t len) const {
return PrefixMatchView{};
}
virtual ~Dict() = default;
};
} // namespace opencc