Skip to content

Commit 0b12e03

Browse files
catamorphismTim Chevalier
authored andcommitted
ICU-23447 MessageFormat ICU4C: Make Function* pointers const
Change MFFunctionRegistry::getFunction() to return const Function* instead of Function*, with Function::call() becoming const.
1 parent 86a0e87 commit 0b12e03

8 files changed

Lines changed: 58 additions & 44 deletions

icu4c/source/i18n/messageformat2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ static UnicodeString reserialize(const UnicodeString& s) {
254254
UnicodeString fallbackStr = functionFallback(rand, functionName);
255255

256256
// Look up the function name
257-
Function* function = lookupFunction(functionName, status);
257+
const Function* function = lookupFunction(functionName, status);
258258

259259
if (U_FAILURE(status)) { // Handle unknown function
260260
// Set error and use the fallback value

icu4c/source/i18n/messageformat2_formatter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ namespace message2 {
276276
return standardMFFunctionRegistry.hasFunction(functionName);
277277
}
278278

279-
Function*
279+
const Function*
280280
MessageFormatter::lookupFunction(const FunctionName& functionName,
281281
UErrorCode& status) const {
282282
NULL_ON_ERROR(status);
@@ -286,7 +286,7 @@ namespace message2 {
286286
}
287287
if (hasCustomMFFunctionRegistry()) {
288288
const MFFunctionRegistry& customMFFunctionRegistry = getCustomMFFunctionRegistry();
289-
Function* function = customMFFunctionRegistry.getFunction(functionName);
289+
const Function* function = customMFFunctionRegistry.getFunction(functionName);
290290
if (function != nullptr) {
291291
return function;
292292
}

icu4c/source/i18n/messageformat2_function_registry.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,9 @@ MFFunctionRegistry::Builder::~Builder() {
107107
}
108108

109109
// Returns non-owned pointer. Returns pointer rather than reference because it can fail.
110-
// Returns non-const because Function is mutable.
111-
Function* MFFunctionRegistry::getFunction(const FunctionName& functionName) const {
110+
const Function* MFFunctionRegistry::getFunction(const FunctionName& functionName) const {
112111
U_ASSERT(functions != nullptr);
113-
return static_cast<Function*>(functions->get(functionName));
112+
return static_cast<const Function*>(functions->get(functionName));
114113
}
115114

116115
UBool MFFunctionRegistry::getDefaultFormatterNameByType(const UnicodeString& type, FunctionName& name) const {
@@ -425,7 +424,7 @@ StandardFunctions::Number::create(bool isInteger, UErrorCode& success) {
425424
LocalPointer<FunctionValue> StandardFunctions::Number::call(const FunctionContext& context,
426425
const FunctionValue& operand,
427426
const FunctionOptions& options,
428-
UErrorCode& errorCode) {
427+
UErrorCode& errorCode) const {
429428
if (U_FAILURE(errorCode)) {
430429
return LocalPointer<FunctionValue>();
431430
}
@@ -940,7 +939,7 @@ LocalPointer<FunctionValue>
940939
StandardFunctions::DateTime::call(const FunctionContext& context,
941940
const FunctionValue& val,
942941
const FunctionOptions& opts,
943-
UErrorCode& errorCode) {
942+
UErrorCode& errorCode) const {
944943
if (U_FAILURE(errorCode)) {
945944
return LocalPointer<FunctionValue>();
946945
}
@@ -1443,7 +1442,7 @@ LocalPointer<FunctionValue>
14431442
StandardFunctions::String::call(const FunctionContext& context,
14441443
const FunctionValue& val,
14451444
const FunctionOptions& opts,
1446-
UErrorCode& errorCode) {
1445+
UErrorCode& errorCode) const {
14471446
if (U_FAILURE(errorCode)) {
14481447
return LocalPointer<FunctionValue>();
14491448
}
@@ -1528,7 +1527,7 @@ StandardFunctions::TestFunctionValue::~TestFunctionValue() {}
15281527
LocalPointer<FunctionValue> StandardFunctions::TestFunction::call(const FunctionContext& context,
15291528
const FunctionValue& operand,
15301529
const FunctionOptions& options,
1531-
UErrorCode& errorCode) {
1530+
UErrorCode& errorCode) const {
15321531
if (U_FAILURE(errorCode)) {
15331532
return LocalPointer<FunctionValue>();
15341533
}

icu4c/source/i18n/messageformat2_function_registry_internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static constexpr std::u16string_view YEAR = u"year";
110110
LocalPointer<FunctionValue> call(const FunctionContext& context,
111111
const FunctionValue& operand,
112112
const FunctionOptions& options,
113-
UErrorCode& errorCode) override;
113+
UErrorCode& errorCode) const override;
114114
virtual ~DateTime();
115115

116116
private:
@@ -144,7 +144,7 @@ static constexpr std::u16string_view YEAR = u"year";
144144
LocalPointer<FunctionValue> call(const FunctionContext& context,
145145
const FunctionValue& operand,
146146
const FunctionOptions& options,
147-
UErrorCode& errorCode) override;
147+
UErrorCode& errorCode) const override;
148148
virtual ~Number();
149149

150150
private:
@@ -223,7 +223,7 @@ static constexpr std::u16string_view YEAR = u"year";
223223
LocalPointer<FunctionValue> call(const FunctionContext& context,
224224
const FunctionValue& val,
225225
const FunctionOptions& opts,
226-
UErrorCode& errorCode) override;
226+
UErrorCode& errorCode) const override;
227227
static String* string(UErrorCode& status);
228228
virtual ~String();
229229

@@ -245,7 +245,7 @@ static constexpr std::u16string_view YEAR = u"year";
245245
LocalPointer<FunctionValue> call(const FunctionContext& context,
246246
const FunctionValue& operand,
247247
const FunctionOptions& options,
248-
UErrorCode& errorCode) override;
248+
UErrorCode& errorCode) const override;
249249
virtual ~TestFunction();
250250
private:
251251
friend class TestFunctionValue;

icu4c/source/i18n/unicode/messageformat2.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,7 @@ namespace message2 {
485485
bool isBuiltInFunction(const FunctionName&) const;
486486
bool isFunction(const FunctionName& fn) const { return isBuiltInFunction(fn) || isCustomFunction(fn); }
487487
void setNotSelectableError(MessageContext&, const InternalValue&, UErrorCode&) const;
488-
// Result is not adopted
489-
Function* lookupFunction(const FunctionName&, UErrorCode&) const;
488+
const Function* lookupFunction(const FunctionName&, UErrorCode&) const;
490489
bool getDefaultFormatterNameByType(const UnicodeString&, FunctionName&) const;
491490

492491
// Checking for resolution errors

icu4c/source/i18n/unicode/messageformat2_function_registry.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ namespace message2 {
5050

5151
public:
5252
/**
53-
* Looks up a function by the name of the function. The result is non-const,
54-
* since functions may have local state. Returns the result by pointer
55-
* rather than by reference since it can fail.
53+
* Looks up a function by the name of the function.
54+
* Returns the result by pointer rather than by reference since it can fail.
5655
*
5756
* @param functionName Name of the desired function.
5857
* @return A pointer to the function registered under `functionName`, or null
@@ -62,7 +61,7 @@ namespace message2 {
6261
* @internal ICU 79 technology preview
6362
* @deprecated This API is for technology preview only.
6463
*/
65-
Function* getFunction(const FunctionName& functionName) const;
64+
const Function* getFunction(const FunctionName& functionName) const;
6665
/**
6766
* Looks up a function by a type tag. This method gets the name of the default formatter registered
6867
* for that type. If no formatter was explicitly registered for this type, it returns false.
@@ -304,7 +303,7 @@ namespace message2 {
304303
virtual LocalPointer<FunctionValue> call(const FunctionContext& context,
305304
const FunctionValue& operand,
306305
const FunctionOptions& options,
307-
UErrorCode& status) = 0;
306+
UErrorCode& status) const = 0;
308307
/**
309308
* Destructor.
310309
*

icu4c/source/test/intltest/messageformat2test.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class PersonNameFunction : public Function {
123123
LocalPointer<FunctionValue> call(const FunctionContext&,
124124
const FunctionValue&,
125125
const FunctionOptions&,
126-
UErrorCode&) override;
126+
UErrorCode&) const override;
127127
virtual ~PersonNameFunction();
128128
PersonNameFunction() {}
129129
};
@@ -154,7 +154,7 @@ class FormattableProperties : public FormattableObject {
154154

155155
class GrammarCasesFunction : public Function {
156156
public:
157-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
157+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
158158
static MFFunctionRegistry customRegistry(UErrorCode&);
159159
};
160160

@@ -173,7 +173,7 @@ class GrammarCasesValue : public FunctionValue {
173173

174174
class ListFunction : public Function {
175175
public:
176-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
176+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
177177
static MFFunctionRegistry customRegistry(UErrorCode&);
178178
ListFunction() {}
179179
virtual ~ListFunction();
@@ -224,7 +224,7 @@ class AdjectiveValue : public FunctionValue {
224224

225225
class ResourceManager : public Function {
226226
public:
227-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
227+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
228228
static MFFunctionRegistry customRegistry(UErrorCode&);
229229
static Hashtable* properties(UErrorCode&);
230230
static UnicodeString propertiesAsString(const Hashtable&);
@@ -249,25 +249,34 @@ class ResourceManagerValue : public FunctionValue {
249249

250250
class NounFunction : public Function {
251251
public:
252-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
252+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
253253
NounFunction() { }
254254
virtual ~NounFunction();
255255
};
256256

257257
class AdjectiveFunction : public Function {
258258
public:
259-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
259+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
260260
AdjectiveFunction() { }
261261
virtual ~AdjectiveFunction();
262262
};
263263

264+
class Counter {
265+
public:
266+
void increment() { value++; }
267+
int32_t get() const { return value; }
268+
Counter() {}
269+
private:
270+
int32_t value = 0;
271+
};
272+
264273
class CounterFunction : public Function {
265274
public:
266-
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) override;
267-
CounterFunction() { }
275+
LocalPointer<FunctionValue> call(const FunctionContext&, const FunctionValue&, const FunctionOptions&, UErrorCode&) const override;
276+
CounterFunction(UErrorCode& errorCode);
268277
virtual ~CounterFunction();
269278
private:
270-
int32_t count = 0; // Number of times the function was called
279+
LocalPointer<Counter> count; // Number of times the function was called
271280
};
272281

273282
class CounterFunctionValue : public FunctionValue {
@@ -277,9 +286,9 @@ class CounterFunctionValue : public FunctionValue {
277286
virtual ~CounterFunctionValue();
278287
private:
279288
friend class CounterFunction;
280-
int32_t& count;
289+
Counter* count;
281290

282-
CounterFunctionValue(int32_t&,
291+
CounterFunctionValue(Counter*,
283292
const FunctionValue&,
284293
const FunctionOptions&,
285294
UErrorCode&);

icu4c/source/test/intltest/messageformat2test_custom.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ static bool hasStringOption(const FunctionOptionsMap& opt,
285285
LocalPointer<FunctionValue> PersonNameFunction::call(const FunctionContext& context,
286286
const FunctionValue& arg,
287287
const FunctionOptions& opts,
288-
UErrorCode& errorCode) {
288+
UErrorCode& errorCode) const {
289289
(void) context;
290290

291291
if (U_FAILURE(errorCode)) {
@@ -404,7 +404,7 @@ LocalPointer<FunctionValue>
404404
GrammarCasesFunction::call(const FunctionContext& context,
405405
const FunctionValue& arg,
406406
const FunctionOptions& opts,
407-
UErrorCode& errorCode) {
407+
UErrorCode& errorCode) const {
408408
(void) context;
409409

410410
if (U_FAILURE(errorCode)) {
@@ -535,7 +535,7 @@ LocalPointer<FunctionValue>
535535
ListFunction::call(const FunctionContext& context,
536536
const FunctionValue& arg,
537537
const FunctionOptions& opts,
538-
UErrorCode& errorCode) {
538+
UErrorCode& errorCode) const {
539539
if (U_FAILURE(errorCode)) {
540540
return LocalPointer<FunctionValue>();
541541
}
@@ -711,7 +711,7 @@ LocalPointer<FunctionValue>
711711
ResourceManager::call(const FunctionContext&,
712712
const FunctionValue& arg,
713713
const FunctionOptions& options,
714-
UErrorCode& errorCode) {
714+
UErrorCode& errorCode) const {
715715
if (U_FAILURE(errorCode)) {
716716
return LocalPointer<FunctionValue>();
717717
}
@@ -878,7 +878,7 @@ LocalPointer<FunctionValue>
878878
NounFunction::call(const FunctionContext&,
879879
const FunctionValue& arg,
880880
const FunctionOptions& opts,
881-
UErrorCode& errorCode) {
881+
UErrorCode& errorCode) const {
882882
if (U_FAILURE(errorCode)) {
883883
return LocalPointer<FunctionValue>();
884884
}
@@ -938,7 +938,7 @@ LocalPointer<FunctionValue>
938938
AdjectiveFunction::call(const FunctionContext&,
939939
const FunctionValue& arg,
940940
const FunctionOptions& opts,
941-
UErrorCode& errorCode) {
941+
UErrorCode& errorCode) const {
942942
if (U_FAILURE(errorCode)) {
943943
return LocalPointer<FunctionValue>();
944944
}
@@ -1014,7 +1014,7 @@ void TestMessageFormat2::testSingleEvaluation(IcuTestErrorCode& errorCode) {
10141014

10151015
MFFunctionRegistry customRegistry(MFFunctionRegistry::Builder(errorCode)
10161016
.adoptFunction(FunctionName("counter"),
1017-
new CounterFunction(),
1017+
new CounterFunction(errorCode),
10181018
errorCode)
10191019
.build());
10201020
UnicodeString name = "name";
@@ -1032,25 +1032,33 @@ void TestMessageFormat2::testSingleEvaluation(IcuTestErrorCode& errorCode) {
10321032
TestUtils::runTestCase(*this, test, errorCode);
10331033
}
10341034

1035+
CounterFunction::CounterFunction(UErrorCode& errorCode) {
1036+
if (U_FAILURE(errorCode)) {
1037+
return;
1038+
}
1039+
Counter* c = new Counter();
1040+
count = LocalPointer(c, errorCode);
1041+
}
1042+
10351043
LocalPointer<FunctionValue>
10361044
CounterFunction::call(const FunctionContext&,
10371045
const FunctionValue& arg,
10381046
const FunctionOptions& opts,
1039-
UErrorCode& errorCode) {
1047+
UErrorCode& errorCode) const {
10401048
if (U_FAILURE(errorCode)) {
10411049
return LocalPointer<FunctionValue>();
10421050
}
10431051

10441052
LocalPointer<FunctionValue>
1045-
v(new CounterFunctionValue(count, arg, std::move(opts), errorCode));
1053+
v(new CounterFunctionValue(count.getAlias(), arg, std::move(opts), errorCode));
10461054
if (!v.isValid()) {
10471055
errorCode = U_MEMORY_ALLOCATION_ERROR;
10481056
}
1049-
count++;
1057+
count->increment();
10501058
return v;
10511059
}
10521060

1053-
CounterFunctionValue::CounterFunctionValue(int32_t& c,
1061+
CounterFunctionValue::CounterFunctionValue(Counter* c,
10541062
const FunctionValue&,
10551063
const FunctionOptions&,
10561064
UErrorCode&) : count(c) {
@@ -1062,7 +1070,7 @@ UnicodeString CounterFunctionValue::formatToString(UErrorCode& status) const {
10621070
return {};
10631071
}
10641072
number::UnlocalizedNumberFormatter nf = number::NumberFormatter::with();
1065-
number::FormattedNumber formattedNumber = nf.locale("en-US").formatInt(count, status);
1073+
number::FormattedNumber formattedNumber = nf.locale("en-US").formatInt(count->get(), status);
10661074
return formattedNumber.toString(status);
10671075
}
10681076

0 commit comments

Comments
 (0)