Skip to content

Commit 099af0c

Browse files
authored
Remove Singleton from Transliterators (#1480)
As part of our on-going efforts to remove the dependency on Singleton, this commit rewrites Transliterators without the Singleton. This is a purely mechanical change, and the behavior of the code should be identical before and after this change. PiperOrigin-RevId: 904852197
1 parent e406e26 commit 099af0c

3 files changed

Lines changed: 87 additions & 91 deletions

File tree

src/composer/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ mozc_cc_library(
271271
hdrs = ["transliterators.h"],
272272
deps = [
273273
"//base:japanese_util",
274-
"//base:singleton",
275274
"//base:util",
276275
"//base:vlog",
277276
"//base/strings:assign",

src/composer/transliterators.cc

Lines changed: 77 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#include "absl/log/log.h"
3737
#include "absl/strings/string_view.h"
3838
#include "base/japanese_util.h"
39-
#include "base/singleton.h"
4039
#include "base/strings/assign.h"
4140
#include "base/util.h"
4241
#include "base/vlog.h"
@@ -88,80 +87,66 @@ bool SplitPrimaryString(const size_t position, const absl::string_view primary,
8887
return true;
8988
}
9089

91-
// Singleton class which always uses a converted string rather than a
92-
// raw string.
93-
class ConversionStringSelector : public internal::TransliteratorInterface {
90+
// Always uses a converted string rather than a raw string.
91+
class ConversionStringSelector {
9492
public:
95-
~ConversionStringSelector() override = default;
96-
97-
std::string Transliterate(const absl::string_view raw,
98-
const absl::string_view converted) const override {
93+
static std::string Transliterate(const absl::string_view raw,
94+
const absl::string_view converted) {
9995
return std::string(converted);
10096
}
10197

102-
// NOTE(komatsu): The first argument, size_t position, should not be
103-
// const because this function overrides the virtual function of
104-
// TransliterateInterface whose first argument is not const.
105-
// Otherwise the Windows compiler (cl.exe) raises an error.
106-
bool Split(size_t position, const absl::string_view raw,
107-
const absl::string_view converted, std::string* raw_lhs,
108-
std::string* raw_rhs, std::string* converted_lhs,
109-
std::string* converted_rhs) const override {
98+
static bool Split(size_t position, const absl::string_view raw,
99+
const absl::string_view converted, std::string* raw_lhs,
100+
std::string* raw_rhs, std::string* converted_lhs,
101+
std::string* converted_rhs) {
110102
return Transliterators::SplitConverted(position, raw, converted, raw_lhs,
111103
raw_rhs, converted_lhs,
112104
converted_rhs);
113105
}
114106
};
115107

116-
// Singleton class which always uses a raw string rather than a
117-
// converted string.
118-
class RawStringSelector : public internal::TransliteratorInterface {
108+
// Always uses a raw string rather than a converted string.
109+
class RawStringSelector {
119110
public:
120-
~RawStringSelector() override = default;
121-
122-
std::string Transliterate(const absl::string_view raw,
123-
const absl::string_view converted) const override {
111+
static std::string Transliterate(const absl::string_view raw,
112+
const absl::string_view converted) {
124113
return std::string(raw);
125114
}
126115

127-
bool Split(size_t position, const absl::string_view raw,
128-
const absl::string_view converted, std::string* raw_lhs,
129-
std::string* raw_rhs, std::string* converted_lhs,
130-
std::string* converted_rhs) const override {
116+
static bool Split(size_t position, const absl::string_view raw,
117+
const absl::string_view converted, std::string* raw_lhs,
118+
std::string* raw_rhs, std::string* converted_lhs,
119+
std::string* converted_rhs) {
131120
return Transliterators::SplitRaw(position, raw, converted, raw_lhs, raw_rhs,
132121
converted_lhs, converted_rhs);
133122
}
134123
};
135124

136-
class HiraganaTransliterator : public internal::TransliteratorInterface {
125+
class HiraganaTransliterator {
137126
public:
138-
~HiraganaTransliterator() override = default;
139-
140-
std::string Transliterate(const absl::string_view raw,
141-
const absl::string_view converted) const override {
127+
static std::string Transliterate(const absl::string_view raw,
128+
const absl::string_view converted) {
142129
std::string full = japanese_util::HalfWidthToFullWidth(converted);
143130
std::string output;
144131
CharacterFormManager::GetCharacterFormManager()->ConvertPreeditString(
145132
full, &output);
146133
return output;
147134
}
148135

149-
bool Split(size_t position, const absl::string_view raw,
150-
const absl::string_view converted, std::string* raw_lhs,
151-
std::string* raw_rhs, std::string* converted_lhs,
152-
std::string* converted_rhs) const override {
136+
static bool Split(size_t position, const absl::string_view raw,
137+
const absl::string_view converted, std::string* raw_lhs,
138+
std::string* raw_rhs, std::string* converted_lhs,
139+
std::string* converted_rhs) {
153140
return Transliterators::SplitConverted(position, raw, converted, raw_lhs,
154141
raw_rhs, converted_lhs,
155142
converted_rhs);
156143
}
157144
};
158145

159-
class FullKatakanaTransliterator : public internal::TransliteratorInterface {
146+
class FullKatakanaTransliterator {
160147
public:
161-
~FullKatakanaTransliterator() override = default;
162-
163-
std::string Transliterate(const absl::string_view raw,
164-
const absl::string_view converted) const override {
148+
static std::string Transliterate(const absl::string_view raw,
149+
const absl::string_view converted) {
165150
std::string t13n = japanese_util::HiraganaToKatakana(converted);
166151
std::string full = japanese_util::HalfWidthToFullWidth(t13n);
167152

@@ -171,37 +156,35 @@ class FullKatakanaTransliterator : public internal::TransliteratorInterface {
171156
return output;
172157
}
173158

174-
bool Split(size_t position, const absl::string_view raw,
175-
const absl::string_view converted, std::string* raw_lhs,
176-
std::string* raw_rhs, std::string* converted_lhs,
177-
std::string* converted_rhs) const override {
159+
static bool Split(size_t position, const absl::string_view raw,
160+
const absl::string_view converted, std::string* raw_lhs,
161+
std::string* raw_rhs, std::string* converted_lhs,
162+
std::string* converted_rhs) {
178163
return Transliterators::SplitConverted(position, raw, converted, raw_lhs,
179164
raw_rhs, converted_lhs,
180165
converted_rhs);
181166
}
182167
};
183168

184-
class HalfKatakanaTransliterator : public internal::TransliteratorInterface {
169+
class HalfKatakanaTransliterator {
185170
public:
186-
~HalfKatakanaTransliterator() override = default;
187-
188171
static std::string HalfKatakanaToHiragana(
189172
const absl::string_view half_katakana) {
190173
std::string full_katakana =
191174
japanese_util::HalfWidthKatakanaToFullWidthKatakana(half_katakana);
192175
return japanese_util::KatakanaToHiragana(full_katakana);
193176
}
194177

195-
std::string Transliterate(const absl::string_view raw,
196-
const absl::string_view converted) const override {
178+
static std::string Transliterate(const absl::string_view raw,
179+
const absl::string_view converted) {
197180
std::string katakana_output = japanese_util::HiraganaToKatakana(converted);
198181
return japanese_util::FullWidthToHalfWidth(katakana_output);
199182
}
200183

201-
bool Split(size_t position, const absl::string_view raw,
202-
const absl::string_view converted, std::string* raw_lhs,
203-
std::string* raw_rhs, std::string* converted_lhs,
204-
std::string* converted_rhs) const override {
184+
static bool Split(size_t position, const absl::string_view raw,
185+
const absl::string_view converted, std::string* raw_lhs,
186+
std::string* raw_rhs, std::string* converted_lhs,
187+
std::string* converted_rhs) {
205188
const std::string half_katakana = Transliterate(raw, converted);
206189
std::string hk_raw_lhs, hk_raw_rhs, hk_converted_lhs, hk_converted_rhs;
207190
const bool result = Transliterators::SplitConverted(
@@ -221,44 +204,58 @@ class HalfKatakanaTransliterator : public internal::TransliteratorInterface {
221204
}
222205
};
223206

224-
class HalfAsciiTransliterator : public internal::TransliteratorInterface {
207+
class HalfAsciiTransliterator {
225208
public:
226-
~HalfAsciiTransliterator() override = default;
227-
228-
std::string Transliterate(const absl::string_view raw,
229-
const absl::string_view converted) const override {
209+
static std::string Transliterate(const absl::string_view raw,
210+
const absl::string_view converted) {
230211
const absl::string_view input = raw.empty() ? converted : raw;
231212
return japanese_util::FullWidthAsciiToHalfWidthAscii(input);
232213
}
233214

234-
bool Split(size_t position, const absl::string_view raw,
235-
const absl::string_view converted, std::string* raw_lhs,
236-
std::string* raw_rhs, std::string* converted_lhs,
237-
std::string* converted_rhs) const override {
215+
static bool Split(size_t position, const absl::string_view raw,
216+
const absl::string_view converted, std::string* raw_lhs,
217+
std::string* raw_rhs, std::string* converted_lhs,
218+
std::string* converted_rhs) {
238219
return Transliterators::SplitRaw(position, raw, converted, raw_lhs, raw_rhs,
239220
converted_lhs, converted_rhs);
240221
}
241222
};
242223

243-
class FullAsciiTransliterator : public internal::TransliteratorInterface {
224+
class FullAsciiTransliterator {
244225
public:
245-
~FullAsciiTransliterator() override = default;
246-
247-
std::string Transliterate(const absl::string_view raw,
248-
const absl::string_view converted) const override {
226+
static std::string Transliterate(const absl::string_view raw,
227+
const absl::string_view converted) {
249228
const absl::string_view input = raw.empty() ? converted : raw;
250229
return japanese_util::HalfWidthAsciiToFullWidthAscii(input);
251230
}
252231

253-
bool Split(size_t position, const absl::string_view raw,
254-
const absl::string_view converted, std::string* raw_lhs,
255-
std::string* raw_rhs, std::string* converted_lhs,
256-
std::string* converted_rhs) const override {
232+
static bool Split(size_t position, const absl::string_view raw,
233+
const absl::string_view converted, std::string* raw_lhs,
234+
std::string* raw_rhs, std::string* converted_lhs,
235+
std::string* converted_rhs) {
257236
return Transliterators::SplitRaw(position, raw, converted, raw_lhs, raw_rhs,
258237
converted_lhs, converted_rhs);
259238
}
260239
};
261240

241+
constexpr internal::TransliteratorInterface kConversionString = {
242+
&ConversionStringSelector::Transliterate,
243+
&ConversionStringSelector::Split};
244+
constexpr internal::TransliteratorInterface kRawString = {
245+
&RawStringSelector::Transliterate, &RawStringSelector::Split};
246+
constexpr internal::TransliteratorInterface kHiragana = {
247+
&HiraganaTransliterator::Transliterate, &HiraganaTransliterator::Split};
248+
constexpr internal::TransliteratorInterface kFullKatakana = {
249+
&FullKatakanaTransliterator::Transliterate,
250+
&FullKatakanaTransliterator::Split};
251+
constexpr internal::TransliteratorInterface kHalfKatakana = {
252+
&HalfKatakanaTransliterator::Transliterate,
253+
&HalfKatakanaTransliterator::Split};
254+
constexpr internal::TransliteratorInterface kFullAscii = {
255+
&FullAsciiTransliterator::Transliterate, &FullAsciiTransliterator::Split};
256+
constexpr internal::TransliteratorInterface kHalfAscii = {
257+
&HalfAsciiTransliterator::Transliterate, &HalfAsciiTransliterator::Split};
258+
262259
} // namespace
263260

264261
// static
@@ -268,23 +265,23 @@ const internal::TransliteratorInterface* Transliterators::GetTransliterator(
268265
DCHECK(transliterator != LOCAL);
269266
switch (transliterator) {
270267
case CONVERSION_STRING:
271-
return Singleton<ConversionStringSelector>::get();
268+
return &kConversionString;
272269
case RAW_STRING:
273-
return Singleton<RawStringSelector>::get();
270+
return &kRawString;
274271
case HIRAGANA:
275-
return Singleton<HiraganaTransliterator>::get();
272+
return &kHiragana;
276273
case FULL_KATAKANA:
277-
return Singleton<FullKatakanaTransliterator>::get();
274+
return &kFullKatakana;
278275
case HALF_KATAKANA:
279-
return Singleton<HalfKatakanaTransliterator>::get();
276+
return &kHalfKatakana;
280277
case FULL_ASCII:
281-
return Singleton<FullAsciiTransliterator>::get();
278+
return &kFullAscii;
282279
case HALF_ASCII:
283-
return Singleton<HalfAsciiTransliterator>::get();
280+
return &kHalfAscii;
284281
default:
285282
LOG(ERROR) << "Unexpected transliterator: " << transliterator;
286283
// As fallback.
287-
return Singleton<ConversionStringSelector>::get();
284+
return &kConversionString;
288285
}
289286
}
290287

src/composer/transliterators.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@
3838
namespace mozc {
3939
namespace composer {
4040
namespace internal {
41-
class TransliteratorInterface {
42-
public:
43-
virtual ~TransliteratorInterface() = default;
44-
41+
// Stateless transliteration rule exposed as a pair of function pointers so
42+
// call sites can keep using `ptr->Transliterate(...)` / `ptr->Split(...)`
43+
// syntax without a virtual dispatch.
44+
struct TransliteratorInterface {
4545
// Return the transliterated string of either raw or converted.
4646
// Determination of which argument is used depends on the
4747
// implementation.
4848
//
4949
// Expected usage examples:
5050
// - HalfKatakanaTransliterator("a", "あ") => "ア"
5151
// - FullAsciiTransliterator("a", "あ") => "a"
52-
virtual std::string Transliterate(absl::string_view raw,
53-
absl::string_view converted) const = 0;
52+
std::string (*Transliterate)(absl::string_view raw,
53+
absl::string_view converted);
5454

5555
// Split raw and converted strings based on the transliteration
5656
// rule. If raw or converted could not be deterministically split,
@@ -64,10 +64,10 @@ class TransliteratorInterface {
6464
// - HalfKatakanaTransliterator(1, "zu", "ず") => false
6565
// (raw_lhs, raw_rhs) => ("す", "゛") fall back strings.
6666
// (conv_lhs, conv_rhs) => ("す", "゛")
67-
virtual bool Split(size_t position, absl::string_view raw,
68-
absl::string_view converted, std::string* raw_lhs,
69-
std::string* raw_rhs, std::string* converted_lhs,
70-
std::string* converted_rhs) const = 0;
67+
bool (*Split)(size_t position, absl::string_view raw,
68+
absl::string_view converted, std::string* raw_lhs,
69+
std::string* raw_rhs, std::string* converted_lhs,
70+
std::string* converted_rhs);
7171
};
7272
} // namespace internal
7373

0 commit comments

Comments
 (0)