summaryrefslogtreecommitdiffstats
path: root/intl/icu_capi/cpp/examples
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /intl/icu_capi/cpp/examples
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'intl/icu_capi/cpp/examples')
-rw-r--r--intl/icu_capi/cpp/examples/bidi/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/bidi/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/bidi/test.cpp93
-rw-r--r--intl/icu_capi/cpp/examples/casemapping/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/casemapping/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/casemapping/test.cpp109
-rw-r--r--intl/icu_capi/cpp/examples/collator/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/collator/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/collator/test.cpp67
-rw-r--r--intl/icu_capi/cpp/examples/datetime/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/datetime/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/datetime/test.cpp116
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal/test.cpp127
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/.gitignore9
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/Makefile53
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/README7
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/node-test.js6
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/package.json6
-rw-r--r--intl/icu_capi/cpp/examples/fixeddecimal_wasm/test.cpp70
-rw-r--r--intl/icu_capi/cpp/examples/locale/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/locale/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/locale/test.cpp107
-rw-r--r--intl/icu_capi/cpp/examples/pluralrules/.gitignore1
-rw-r--r--intl/icu_capi/cpp/examples/pluralrules/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/pluralrules/test.cpp38
-rw-r--r--intl/icu_capi/cpp/examples/properties/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/properties/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/properties/test.cpp251
-rw-r--r--intl/icu_capi/cpp/examples/segmenter/.gitignore2
-rw-r--r--intl/icu_capi/cpp/examples/segmenter/Makefile28
-rw-r--r--intl/icu_capi/cpp/examples/segmenter/test.cpp160
33 files changed, 1488 insertions, 0 deletions
diff --git a/intl/icu_capi/cpp/examples/bidi/.gitignore b/intl/icu_capi/cpp/examples/bidi/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/bidi/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/bidi/Makefile b/intl/icu_capi/cpp/examples/bidi/Makefile
new file mode 100644
index 0000000000..594ca66c37
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/bidi/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib --features compiled_data
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/bidi/test.cpp b/intl/icu_capi/cpp/examples/bidi/test.cpp
new file mode 100644
index 0000000000..629cf752ce
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/bidi/test.cpp
@@ -0,0 +1,93 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XDataProvider.hpp"
+#include "../../include/ICU4XBidi.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+
+int main() {
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+ auto bidi = ICU4XBidi::create(dp).ok().value();
+
+ // Written char-by-char to avoid messing up certain text editors.
+ std::string_view str =
+ "א"
+ "ב"
+ "ג"
+ "a"
+ "b"
+ "c"
+ "\n"
+ "a"
+ "b"
+ "c"
+ "א"
+ "ב"
+ "ג";
+
+ // reordered string is same for both lines
+ std::string_view reordered_expected =
+ "a"
+ "b"
+ "c"
+ "ג"
+ "ב"
+ "א";
+ auto bidi_info = bidi.for_text(str, ICU4XBidi::level_ltr());
+ auto n_para = bidi_info.paragraph_count();
+ if (n_para != 2) {
+ std::cout << "Expected 2 paragraphs, found " << n_para << std::endl;
+ return 1;
+ }
+
+ auto para = bidi_info.paragraph_at(0).value();
+
+ auto size = para.size();
+ if (size != 10) {
+ std::cout << "Expected paragraph of size 10, found " << size << std::endl;
+ return 1;
+ }
+
+ // The first paragraph's first strongly directional character is RTL
+ uint8_t level = para.level_at(0);
+ std::cout << "Level of first paragraph at index 0 is " << unsigned(level) << std::endl;
+ if (!ICU4XBidi::level_is_rtl(level)) {
+ std::cout << "Expected level at index 0 to be RTL" << std::endl;
+ return 1;
+ }
+
+
+ std::string reordered = para.reorder_line(0, 9).ok().value();
+ std::cout << "Reordered paragraph: " << reordered << std::endl;
+
+ if (reordered != reordered) {
+ std::cout << "Found incorrect reordering, expected: " << reordered << std::endl;
+ }
+
+ para.set_paragraph_in_text(1).ok().value();
+
+ size = para.size();
+ if (size != 9) {
+ std::cout << "Expected paragraph of size 9, found " << size << std::endl;
+ return 1;
+ }
+
+ // The second paragraph's first strongly directional character is LTR
+ level = para.level_at(0);
+ std::cout << "Level of second paragraph at index 0 is " << unsigned(level) << std::endl;
+ if (!ICU4XBidi::level_is_ltr(level)) {
+ std::cout << "Expected level at index 0 to be LTR" << std::endl;
+ return 1;
+ }
+ reordered = para.reorder_line(10, 19).ok().value();
+ std::cout << "Reordered paragraph: " << reordered << std::endl;
+
+ if (reordered != reordered) {
+ std::cout << "Found incorrect reordering, expected: " << reordered << std::endl;
+ }
+
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/casemapping/.gitignore b/intl/icu_capi/cpp/examples/casemapping/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/casemapping/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/casemapping/Makefile b/intl/icu_capi/cpp/examples/casemapping/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/casemapping/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/casemapping/test.cpp b/intl/icu_capi/cpp/examples/casemapping/test.cpp
new file mode 100644
index 0000000000..3559c5435d
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/casemapping/test.cpp
@@ -0,0 +1,109 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XCaseMapper.hpp"
+#include "../../include/ICU4XLogger.hpp"
+#include "../../include/ICU4XDataProvider.hpp"
+#include "../../include/ICU4XCodePointSetBuilder.hpp"
+#include "../../include/ICU4XTitlecaseOptionsV1.hpp"
+
+#include <iostream>
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XLocale und = ICU4XLocale::create_from_string("und").ok().value();
+ ICU4XLocale greek = ICU4XLocale::create_from_string("el").ok().value();
+ ICU4XLocale turkish = ICU4XLocale::create_from_string("tr").ok().value();
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+
+ ICU4XCaseMapper cm = ICU4XCaseMapper::create(dp).ok().value();
+
+ ICU4XTitlecaseOptionsV1 tc_options = ICU4XTitlecaseOptionsV1::default_options();
+
+ std::string out = cm.lowercase("hEllO WorLd", und).ok().value();
+ std::cout << "Lowercased value is " << out << std::endl;
+ if (out != "hello world") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+ out = cm.uppercase("hEllO WorLd", und).ok().value();
+ std::cout << "Uppercased value is " << out << std::endl;
+ if (out != "HELLO WORLD") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ out = cm.titlecase_segment_with_only_case_data_v1("hEllO WorLd", und, tc_options).ok().value();
+ std::cout << "Titlecased value is " << out << std::endl;
+ if (out != "Hello world") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+
+ // locale-specific behavior
+
+ out = cm.uppercase("Γειά σου Κόσμε", und).ok().value();
+ std::cout << "Uppercased value is " << out << std::endl;
+ if (out != "ΓΕΙΆ ΣΟΥ ΚΌΣΜΕ") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ out = cm.uppercase("Γειά σου Κόσμε", greek).ok().value();
+ std::cout << "Uppercased value is " << out << std::endl;
+ if (out != "ΓΕΙΑ ΣΟΥ ΚΟΣΜΕ") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ out = cm.uppercase("istanbul", und).ok().value();
+ std::cout << "Uppercased value is " << out << std::endl;
+ if (out != "ISTANBUL") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ out = cm.uppercase("istanbul", turkish).ok().value();
+ std::cout << "Uppercased value is " << out << std::endl;
+ if (out != "İSTANBUL") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+
+ out = cm.fold("ISTANBUL").ok().value();
+ std::cout << "Folded value is " << out << std::endl;
+ if (out != "istanbul") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ out = cm.fold_turkic("ISTANBUL").ok().value();
+ std::cout << "Turkic-folded value is " << out << std::endl;
+ if (out != "ıstanbul") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ ICU4XCodePointSetBuilder builder = ICU4XCodePointSetBuilder::create();
+
+ cm.add_case_closure_to('s', builder);
+
+ auto set = builder.build();
+
+ if (set.contains('s')) {
+ std::cout << "Set contains 's', which was not expected" << std::endl;
+ return 1;
+ }
+ if (!set.contains('S')) {
+ std::cout << "Set does not 'S', which was not expected" << std::endl;
+ return 1;
+ }
+ if (!set.contains(U'ſ')) {
+ std::cout << "Set does not 'S', which was not expected" << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/collator/.gitignore b/intl/icu_capi/cpp/examples/collator/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/collator/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/collator/Makefile b/intl/icu_capi/cpp/examples/collator/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/collator/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/collator/test.cpp b/intl/icu_capi/cpp/examples/collator/test.cpp
new file mode 100644
index 0000000000..20cd0d1315
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/collator/test.cpp
@@ -0,0 +1,67 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XCollator.hpp"
+#include "../../include/ICU4XDataProvider.hpp"
+#include "../../include/ICU4XLocale.hpp"
+#include "../../include/ICU4XLogger.hpp"
+#include "../../include/ICU4XOrdering.hpp"
+
+#include <iostream>
+#include <string_view>
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+
+ // test 01 - basic collation example, default CollatorOptions
+
+ std::string_view manna{ "manna" };
+ std::string_view manana{ "mañana" };
+
+ ICU4XLocale locale = ICU4XLocale::create_from_string("en").ok().value();
+ ICU4XCollatorOptionsV1 options = {};
+ ICU4XCollator collator = ICU4XCollator::create_v1(dp, locale, options).ok().value();
+ ICU4XOrdering actual = collator.compare(manna, manana);
+
+ if (actual != ICU4XOrdering::Greater) {
+ std::cout << "Expected manna > mañana for locale " << locale.to_string().ok().value() << std::endl;
+ return 1;
+ }
+
+ locale = ICU4XLocale::create_from_string("es").ok().value();
+ collator = ICU4XCollator::create_v1(dp, locale, options).ok().value();
+ actual = collator.compare(manna, manana);
+
+ if (actual != ICU4XOrdering::Less) {
+ std::cout << "Expected manna < mañana for locale " << locale.to_string().ok().value()<< std::endl;
+ return 1;
+ }
+
+ // test 02 - collation strength example, requires non-default CollatorOptions
+
+ std::string_view as{ "as" };
+ std::string_view graveAs{ "às" };
+
+ locale = ICU4XLocale::create_from_string("en").ok().value();
+ options.strength = ICU4XCollatorStrength::Primary;
+ collator = ICU4XCollator::create_v1(dp, locale, options).ok().value();
+ actual = collator.compare(as, graveAs);
+
+ if (actual != ICU4XOrdering::Equal) {
+ std::cout << "Expected as = às for primary strength, locale " << locale.to_string().ok().value()<< std::endl;
+ return 1;
+ }
+
+ options.strength = ICU4XCollatorStrength::Secondary;
+ collator = ICU4XCollator::create_v1(dp, locale, options).ok().value();
+ actual = collator.compare(as, graveAs);
+
+ if (actual != ICU4XOrdering::Less) {
+ std::cout << "Expected as < às for secondary strength, locale " << locale.to_string().ok().value()<< std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/datetime/.gitignore b/intl/icu_capi/cpp/examples/datetime/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/datetime/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/datetime/Makefile b/intl/icu_capi/cpp/examples/datetime/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/datetime/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/datetime/test.cpp b/intl/icu_capi/cpp/examples/datetime/test.cpp
new file mode 100644
index 0000000000..4e86e86e52
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/datetime/test.cpp
@@ -0,0 +1,116 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XGregorianDateFormatter.hpp"
+#include "../../include/ICU4XGregorianDateTimeFormatter.hpp"
+#include "../../include/ICU4XDateTimeFormatter.hpp"
+#include "../../include/ICU4XTimeFormatter.hpp"
+#include "../../include/ICU4XDataStruct.hpp"
+#include "../../include/ICU4XLogger.hpp"
+#include "../../include/ICU4XCustomTimeZone.hpp"
+#include "../../include/ICU4XIanaToBcp47Mapper.hpp"
+#include "../../include/ICU4XBcp47ToIanaMapper.hpp"
+#include "../../include/ICU4XGregorianZonedDateTimeFormatter.hpp"
+#include "../../include/ICU4XZonedDateTimeFormatter.hpp"
+
+#include <atomic>
+#include <iostream>
+#include <array>
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XLocale locale = ICU4XLocale::create_from_string("es").ok().value();
+ std::cout << "Running test for locale " << locale.to_string().ok().value() << std::endl;
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+
+ ICU4XIsoDateTime date = ICU4XIsoDateTime::create(2022, 07, 11, 13, 06, 42, 0).ok().value();
+
+ ICU4XTimeFormatter tf = ICU4XTimeFormatter::create_with_length(dp, locale, ICU4XTimeLength::Short).ok().value();
+ std::string out = tf.format_iso_datetime(date).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "13:06") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ ICU4XGregorianDateFormatter df = ICU4XGregorianDateFormatter::create_with_length(dp, locale, ICU4XDateLength::Full).ok().value();
+ out = df.format_iso_datetime(date).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "lunes, 11 de julio de 2022") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ ICU4XGregorianDateTimeFormatter dtf = ICU4XGregorianDateTimeFormatter::create_with_lengths(dp, locale, ICU4XDateLength::Medium, ICU4XTimeLength::Short).ok().value();
+ out = dtf.format_iso_datetime(date).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "11 jul 2022, 13:06") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ locale = ICU4XLocale::create_from_string("en-u-ca-japanese").ok().value();
+ ICU4XCalendar cal = ICU4XCalendar::create_for_locale(dp, locale).ok().value();
+ ICU4XDateTime any_date = ICU4XDateTime::create_from_iso_in_calendar(2020, 10, 5, 13, 33, 15, 0, cal).ok().value();
+ ICU4XDateTimeFormatter any_dtf = ICU4XDateTimeFormatter::create_with_lengths(dp, locale, ICU4XDateLength::Medium, ICU4XTimeLength::Short).ok().value();
+ out = any_dtf.format_datetime(any_date).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "Oct 5, 2 Reiwa, 1:33\u202fPM") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ ICU4XCustomTimeZone time_zone = ICU4XCustomTimeZone::create_from_string("-06:00").ok().value();
+ int32_t offset = time_zone.gmt_offset_seconds().ok().value();
+ if (offset != -21600) {
+ std::cout << "GMT offset doesn't parse" << std::endl;
+ return 1;
+ }
+ ICU4XMetazoneCalculator mzcalc = ICU4XMetazoneCalculator::create(dp).ok().value();
+ ICU4XIanaToBcp47Mapper mapper = ICU4XIanaToBcp47Mapper::create(dp).ok().value();
+ time_zone.try_set_iana_time_zone_id(mapper, "america/chicago").ok().value();
+ std::string time_zone_id_return = time_zone.time_zone_id().ok().value();
+ if (time_zone_id_return != "uschi") {
+ std::cout << "Time zone ID does not roundtrip: " << time_zone_id_return << std::endl;
+ return 1;
+ }
+ ICU4XBcp47ToIanaMapper reverse_mapper = ICU4XBcp47ToIanaMapper::create(dp).ok().value();
+ std::string recovered_iana_id = reverse_mapper.get("uschi").ok().value();
+ if (recovered_iana_id != "America/Chicago") {
+ std::cout << "Time zone ID does not canonicalize to IANA: " << recovered_iana_id << std::endl;
+ return 1;
+ }
+ ICU4XIsoDateTime local_datetime = ICU4XIsoDateTime::create(2022, 8, 25, 0, 0, 0, 0).ok().value();
+ time_zone.maybe_calculate_metazone(mzcalc, local_datetime);
+ std::string metazone_id_return = time_zone.metazone_id().ok().value();
+ if (metazone_id_return != "amce") {
+ std::cout << "Metazone ID not calculated correctly; got " << metazone_id_return << std::endl;
+ return 1;
+ }
+ // Note: The daylight time switch should normally come from TZDB calculations.
+ time_zone.set_daylight_time();
+ std::string zone_variant_return = time_zone.zone_variant().ok().value();
+ if (zone_variant_return != "dt") {
+ std::cout << "Zone variant not calculated correctly; got " << zone_variant_return << std::endl;
+ return 1;
+ }
+
+ ICU4XGregorianZonedDateTimeFormatter gzdtf = ICU4XGregorianZonedDateTimeFormatter::create_with_lengths(dp, locale, ICU4XDateLength::Full, ICU4XTimeLength::Full).ok().value();
+ out = gzdtf.format_iso_datetime_with_custom_time_zone(date, time_zone).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "Monday, July 11, 2022, 1:06:42\u202fPM Central Daylight Time") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ ICU4XZonedDateTimeFormatter zdtf = ICU4XZonedDateTimeFormatter::create_with_lengths(dp, locale, ICU4XDateLength::Full, ICU4XTimeLength::Full).ok().value();
+ out = zdtf.format_datetime_with_custom_time_zone(any_date, time_zone).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "Monday, October 5, 2 Reiwa, 1:33:15\u202fPM Central Daylight Time") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal/.gitignore b/intl/icu_capi/cpp/examples/fixeddecimal/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal/Makefile b/intl/icu_capi/cpp/examples/fixeddecimal/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal/test.cpp b/intl/icu_capi/cpp/examples/fixeddecimal/test.cpp
new file mode 100644
index 0000000000..365d3972c5
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal/test.cpp
@@ -0,0 +1,127 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XFixedDecimalFormatter.hpp"
+#include "../../include/ICU4XDataStruct.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+#include <array>
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XLocale locale = ICU4XLocale::create_from_string("bn").ok().value();
+ std::cout << "Running test for locale " << locale.to_string().ok().value() << std::endl;
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+ ICU4XFixedDecimalFormatter fdf = ICU4XFixedDecimalFormatter::create_with_grouping_strategy(
+ dp, locale, ICU4XFixedDecimalGroupingStrategy::Auto).ok().value();
+
+ ICU4XFixedDecimal decimal = ICU4XFixedDecimal::create_from_u64(1000007);
+ std::string out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "১০,০০,০০৭") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ std::string out2;
+ fdf.format_to_writeable(decimal, out2);
+ std::cout << "Formatted writeable value is " << out2 << std::endl;
+ if (out2 != "১০,০০,০০৭") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal.multiply_pow10(2);
+ decimal.set_sign(ICU4XFixedDecimalSign::Negative);
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Value x100 and negated is " << out << std::endl;
+ if (out != "-১০,০০,০০,৭০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal = ICU4XFixedDecimal::create_from_f64_with_floating_precision(100.01).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted float value is " << out << std::endl;
+ if (out != "১০০.০১") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal.pad_end(-4);
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted left-padded float value is " << out << std::endl;
+ if (out != "১০০.০১০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal.pad_start(4);
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted right-padded float value is " << out << std::endl;
+ if (out != "০,১০০.০১০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal.set_max_position(3);
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted truncated float value is " << out << std::endl;
+ if (out != "১০০.০১০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal = ICU4XFixedDecimal::create_from_f64_with_lower_magnitude(100.0006, -2).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted float value from precision 2 is " << out << std::endl;
+ if (out != "১০০.০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal = ICU4XFixedDecimal::create_from_f64_with_significant_digits(100.0006, 5).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted float value with 5 digits is " << out << std::endl;
+ if (out != "১০০.০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ std::array<char32_t, 10> digits = {U'a', U'b', U'c', U'd', U'e', U'f', U'g', U'h', U'i', U'j'};
+
+ auto data = ICU4XDataStruct::create_decimal_symbols_v1("+", "", "-", "", "/", "_", 4, 2, 4, digits).ok().value();
+
+ fdf = ICU4XFixedDecimalFormatter::create_with_decimal_symbols_v1(data, ICU4XFixedDecimalGroupingStrategy::Auto).ok().value();
+
+ decimal = ICU4XFixedDecimal::create_from_f64_with_floating_precision(123456.8901).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted float value for custom numeric system is " << out << std::endl;
+ if (out != "bcdefg/ijab") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+ decimal = ICU4XFixedDecimal::create_from_f64_with_floating_precision(123451234567.8901).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted float value for custom numeric system is " << out << std::endl;
+ if (out != "bc_de_fb_cd_efgh/ijab") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ locale = ICU4XLocale::create_from_string("th-u-nu-thai").ok().value();
+ std::cout << "Running test for locale " << locale.to_string().ok().value() << std::endl;
+ fdf = ICU4XFixedDecimalFormatter::create_with_grouping_strategy(
+ dp, locale, ICU4XFixedDecimalGroupingStrategy::Auto).ok().value();
+
+ decimal = ICU4XFixedDecimal::create_from_f64_with_floating_precision(123456.8901).ok().value();
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "๑๒๓,๔๕๖.๘๙๐๑") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/.gitignore b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/.gitignore
new file mode 100644
index 0000000000..100536298e
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/.gitignore
@@ -0,0 +1,9 @@
+web-version.html
+web-version.wasm
+web-version.js
+node-version.js
+node-version.wasm
+package-lock.json
+node_modules
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/Makefile b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/Makefile
new file mode 100644
index 0000000000..b2c0a018cf
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/Makefile
@@ -0,0 +1,53 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := build
+.PHONY: build test clean serve build-host test-host
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+ICU4X_NIGHTLY_TOOLCHAIN ?= "nightly-2022-12-26"
+
+CXX?=g++
+EMCC?=emcc
+
+$(ALL_HEADERS):
+
+crate/target/debug/libcrate.a: FORCE
+ cd crate && cargo build
+
+a.out: crate/target/debug/libcrate.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp crate/target/debug/libcrate.a -ldl -lpthread -lm -g
+
+crate/target/wasm32-unknown-emscripten/release/libcrate.a: FORCE
+ rustup toolchain install ${ICU4X_NIGHTLY_TOOLCHAIN}
+ rustup component add rust-src --toolchain ${ICU4X_NIGHTLY_TOOLCHAIN}
+ RUSTFLAGS="-Cpanic=abort -Copt-level=s -Clto -Cembed-bitcode" \
+ cd crate && cargo +${ICU4X_NIGHTLY_TOOLCHAIN} build --release --target wasm32-unknown-emscripten -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort
+
+web-version.html: crate/target/wasm32-unknown-emscripten/release/libcrate.a $(ALL_HEADERS) test.cpp
+ $(EMCC) -std=c++17 test.cpp crate/target/wasm32-unknown-emscripten/release/libcrate.a -ldl -lpthread -lm -g -o web-version.html --bind --emrun -sENVIRONMENT=web -sWASM=1 -sEXPORT_ES6=1 -sMODULARIZE=1
+
+node-version.js: crate/target/wasm32-unknown-emscripten/release/libcrate.a $(ALL_HEADERS) test.cpp
+ $(EMCC) -std=c++17 test.cpp crate/target/wasm32-unknown-emscripten/release/libcrate.a -ldl -lpthread -lm -g -o node-version.js --bind -sWASM=1 -sENVIRONMENT=node -sWASM_ASYNC_COMPILATION=0 -DNOMAIN
+
+build: web-version.html node-version.js
+
+test: node-version.js
+ exec node ./node-test.js
+
+serve: web-version.html
+ emrun web-version.html
+
+# These make it possible to ensure that the C++ code is up to date with the bindings
+# without needing to set up emsdk. This way `make test-ffi` works without emsdk.
+build-host: a.out
+
+test-host: build-host
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f crate/target/wasm32-unknown-emscripten/release/libcrate.a
+ rm -f crate/target/debug/libcrate.a
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/README b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/README
new file mode 100644
index 0000000000..1299d40bf0
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/README
@@ -0,0 +1,7 @@
+This folder contains a test for calling ICU4X from C++ compiled to WASM (via emscripten).
+
+You need the [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html) downloaded and sourced into your environment to run this.
+
+There are two ways to run the test. Firstly, you can call `make test`, which runs `node node-test.js` after building the appropriate WASM files. This runs a CLI test with the fixed decimal example in test.cpp.
+
+The other way is to run `make serve`, which will open a web page running test.cpp in your browser. \ No newline at end of file
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/node-test.js b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/node-test.js
new file mode 100644
index 0000000000..d4a7a99d41
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/node-test.js
@@ -0,0 +1,6 @@
+wasm = require("./node-version.js");
+
+const exitCode = wasm.runFixedDecimal();
+if (exitCode !== 0) {
+ throw new Error(`Test failed with exit code ${exitCode}`)
+}
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/package.json b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/package.json
new file mode 100644
index 0000000000..5567954da2
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/package.json
@@ -0,0 +1,6 @@
+{
+ "type": "commonjs",
+ "scripts": {
+ "test": "node node-test.js"
+ }
+}
diff --git a/intl/icu_capi/cpp/examples/fixeddecimal_wasm/test.cpp b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/test.cpp
new file mode 100644
index 0000000000..e9bca35216
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/fixeddecimal_wasm/test.cpp
@@ -0,0 +1,70 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#ifdef __EMSCRIPTEN__
+#include <emscripten/bind.h>
+#endif
+
+#include "../../include/ICU4XFixedDecimalFormatter.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+
+extern "C" void diplomat_init();
+extern "C" void log_js(char* s, u_int len) {
+ std::cout<<"LOG: " << std::string_view(s, len) <<std::endl;
+}
+extern "C" void warn_js(char* s, u_int len) {
+ std::cout<<"WARN: " << std::string_view(s, len) <<std::endl;
+}
+
+int runFixedDecimal() {
+#ifdef __EMSCRIPTEN__
+ diplomat_init();
+ ICU4XLogger::init_console_logger();
+#endif
+ ICU4XLocale locale = ICU4XLocale::create_from_string("bn").ok().value();
+ std::cout << "Running test for locale " << locale.to_string().ok().value() << std::endl;
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+ ICU4XFixedDecimalFormatter fdf = ICU4XFixedDecimalFormatter::create_with_grouping_strategy(
+ dp, locale, ICU4XFixedDecimalGroupingStrategy::Auto).ok().value();
+
+ ICU4XFixedDecimal decimal = ICU4XFixedDecimal::create_from_u64(1000007);
+ std::string out = fdf.format(decimal).ok().value();
+ std::cout << "Formatted value is " << out << std::endl;
+ if (out != "১০,০০,০০৭") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ std::string out2;
+ fdf.format_to_writeable(decimal, out2);
+ std::cout << "Formatted writeable value is " << out2 << std::endl;
+ if (out2 != "১০,০০,০০৭") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+
+ decimal.multiply_pow10(2);
+ decimal.set_sign(ICU4XFixedDecimalSign::Negative);
+ out = fdf.format(decimal).ok().value();
+ std::cout << "Value x100 and negated is " << out << std::endl;
+ if (out != "-১০,০০,০০,৭০০") {
+ std::cout << "Output does not match expected output" << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+#ifdef __EMSCRIPTEN__
+EMSCRIPTEN_BINDINGS(testFixedDecimal) {
+ emscripten::function("runFixedDecimal", &runFixedDecimal);
+}
+#endif
+
+#ifndef NOMAIN
+int main() {
+ return runFixedDecimal();
+}
+#endif
diff --git a/intl/icu_capi/cpp/examples/locale/.gitignore b/intl/icu_capi/cpp/examples/locale/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/locale/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/locale/Makefile b/intl/icu_capi/cpp/examples/locale/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/locale/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/locale/test.cpp b/intl/icu_capi/cpp/examples/locale/test.cpp
new file mode 100644
index 0000000000..b2bba0ceff
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/locale/test.cpp
@@ -0,0 +1,107 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XLocale.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+
+static bool test_locale(ICU4XLocale &locale, std::string_view expectedString,
+ const char *message) {
+ std::string actualString = locale.to_string().ok().value();
+ std::cout << message << ": \"" << actualString << "\"" << std::endl;
+ if (actualString != expectedString) {
+ std::cout << "Locale did not match expected: \"" << expectedString << "\""
+ << std::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool test_string(std::string_view actualString,
+ std::string_view expectedString, const char *message) {
+ std::cout << message << ": \"" << actualString << "\"" << std::endl;
+ if (actualString != expectedString) {
+ std::cout << "String did not match expected: \"" << expectedString << "\""
+ << std::endl;
+ return false;
+ }
+ return true;
+}
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XLocale locale = ICU4XLocale::create_from_string("es-ES").ok().value();
+ if (!test_locale(locale, "es-ES", "Created a locale")) {
+ return 1;
+ }
+
+ locale.set_language("en").ok();
+ if (!test_locale(locale, "en-ES", "The language can be updated")) {
+ return 1;
+ }
+
+ locale.set_region("US").ok();
+ if (!test_locale(locale, "en-US", "The region can be updated")) {
+ return 1;
+ }
+
+ locale.set_script("Latn").ok();
+ if (!test_locale(locale, "en-Latn-US", "The script can be updated")) {
+ return 1;
+ }
+
+ if (!test_string(locale.language().ok().value(), "en",
+ "The language can be accessed")) {
+ return 1;
+ }
+ if (!test_string(locale.region().ok().value(), "US",
+ "The region can be accessed")) {
+ return 1;
+ }
+ if (!test_string(locale.script().ok().value(), "Latn",
+ "The script can be accessed")) {
+ return 1;
+ }
+
+ locale.set_language("").ok();
+ if (!test_locale(locale, "und-Latn-US", "Removed the language")) {
+ return 1;
+ }
+
+ locale.set_region("").ok();
+ if (locale.region().is_ok()) {
+ std::cout << "Expected region to be an err" << std::endl;
+ return 1;
+ }
+ if (!test_locale(locale, "und-Latn", "Removed the region")) {
+ return 1;
+ }
+
+ locale.set_script("").ok();
+ if (locale.script().is_ok()) {
+ std::cout << "Expected script to be an err" << std::endl;
+ return 1;
+ }
+ if (!test_locale(locale, "und", "Removed the script")) {
+ return 1;
+ }
+
+ locale = ICU4XLocale::create_from_string("en-US-u-hc-h12").ok().value();
+ if (!test_string(locale.get_unicode_extension("hc").ok().value(), "h12",
+ "The unicode extension can be accessed")) {
+ return 1;
+ }
+ if (!test_string(locale.basename().ok().value(), "en-US",
+ "The basename can be accessed")) {
+ return 1;
+ }
+
+ locale = ICU4XLocale::create_und();
+ if (!test_locale(locale, "und", "Created an undefined locale")) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/pluralrules/.gitignore b/intl/icu_capi/cpp/examples/pluralrules/.gitignore
new file mode 100644
index 0000000000..cba7efc8ef
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/pluralrules/.gitignore
@@ -0,0 +1 @@
+a.out
diff --git a/intl/icu_capi/cpp/examples/pluralrules/Makefile b/intl/icu_capi/cpp/examples/pluralrules/Makefile
new file mode 100644
index 0000000000..fd43d93d00
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/pluralrules/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib -p icu_provider --features provider_fs,deserialize_json
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/pluralrules/test.cpp b/intl/icu_capi/cpp/examples/pluralrules/test.cpp
new file mode 100644
index 0000000000..254e96ecef
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/pluralrules/test.cpp
@@ -0,0 +1,38 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XPluralRules.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+
+const std::string_view path = "../../../../../provider/datagen/tests/data/json/";
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XLocale locale = ICU4XLocale::create_from_string("ar").ok().value();
+ std::cout << "Running test for locale " << locale.to_string().ok().value() << std::endl;
+ ICU4XDataProvider dp = ICU4XDataProvider::create_fs(path).ok().value();
+ ICU4XPluralRules pr = ICU4XPluralRules::create_cardinal(dp, locale).ok().value();
+
+ ICU4XPluralOperands op = ICU4XPluralOperands::create_from_string("3").ok().value();
+ ICU4XPluralCategory cat = pr.category_for(op);
+
+ std::cout << "Category is " << static_cast<int32_t>(cat)
+ << " (should be " << static_cast<int32_t>(ICU4XPluralCategory::Few) << ")"
+ << std::endl;
+ if (cat != ICU4XPluralCategory::Few) {
+ return 1;
+ }
+
+ op = ICU4XPluralOperands::create_from_string("1011.0").ok().value();
+ cat = pr.category_for(op);
+ std::cout << "Category is " << static_cast<int32_t>(cat)
+ << " (should be " << static_cast<int32_t>(ICU4XPluralCategory::Many) << ")"
+ << std::endl;
+ if (cat != ICU4XPluralCategory::Many) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/properties/.gitignore b/intl/icu_capi/cpp/examples/properties/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/properties/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/properties/Makefile b/intl/icu_capi/cpp/examples/properties/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/properties/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/properties/test.cpp b/intl/icu_capi/cpp/examples/properties/test.cpp
new file mode 100644
index 0000000000..24583041df
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/properties/test.cpp
@@ -0,0 +1,251 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XCodePointSetData.hpp"
+#include "../../include/ICU4XUnicodeSetData.hpp"
+#include "../../include/ICU4XCodePointMapData16.hpp"
+#include "../../include/ICU4XCodePointMapData8.hpp"
+#include "../../include/ICU4XPropertyValueNameToEnumMapper.hpp"
+#include "../../include/ICU4XGeneralCategoryNameToMaskMapper.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+
+int test_set_property(ICU4XCodePointSetData data, char32_t included, char32_t excluded) {
+ bool contains1 = data.contains(included);
+ bool contains2 = data.contains(excluded);
+ std::cout << std::hex; // print hex for U+####
+ if (contains1 && !contains2) {
+ std::cout << "Set correctly contains U+" << included << " and not U+" << excluded << std::endl;
+ } else {
+ std::cout << "Set returns wrong result on U+" << included << " or U+" << excluded << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+int test_map_16_property(ICU4XCodePointMapData16 data, char32_t sample, uint32_t expected) {
+ uint32_t actual = data.get(sample);
+ std::cout << std::hex; // print hex for U+####
+ if (actual == expected) {
+ std::cout << "Code point U+" << sample << " correctly mapped to 0x" << actual << std::endl;
+ } else {
+ std::cout << "Code point U+" << sample << " incorrectly mapped to 0x" << actual << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+int test_map_8_property(ICU4XCodePointMapData8 data, char32_t sample, uint32_t expected) {
+ uint32_t actual = data.get(sample);
+ std::cout << std::hex; // print hex for U+####
+ if (actual == expected) {
+ std::cout << "Code point U+" << sample << " correctly mapped to 0x" << actual << std::endl;
+ } else {
+ std::cout << "Code point U+" << sample << " incorrectly mapped to 0x" << actual << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+int main() {
+ ICU4XLogger::init_simple_logger();
+ ICU4XDataProvider dp = ICU4XDataProvider::create_compiled();
+ int result;
+
+ result = test_set_property(
+ ICU4XCodePointSetData::load_ascii_hex_digit(dp).ok().value(),
+ u'3',
+ u'੩'
+ );
+ if (result != 0) {
+ return result;
+ }
+
+ result = test_map_16_property(
+ ICU4XCodePointMapData16::load_script(dp).ok().value(),
+ u'木',
+ 17 // Script::Han
+ );
+ if (result != 0) {
+ return result;
+ }
+
+ result = test_map_8_property(
+ ICU4XCodePointMapData8::load_general_category(dp).ok().value(),
+ u'木',
+ 5 // GeneralCategory::OtherLetter
+ );
+ if (result != 0) {
+ return result;
+ }
+
+ result = test_map_8_property(
+ ICU4XCodePointMapData8::load_bidi_class(dp).ok().value(),
+ u'ع',
+ 13 // GeneralCategory::ArabicLetter
+ );
+ if (result != 0) {
+ return result;
+ }
+
+ ICU4XUnicodeSetData basic_emoji = ICU4XUnicodeSetData::load_basic_emoji(dp).ok().value();
+ std::string letter = u8"hello";
+
+ if (!basic_emoji.contains_char(U'🔥')) {
+ std::cout << "Character 🔥 not found in Basic_Emoji set" << std::endl;
+ result = 1;
+ }
+
+ if (!basic_emoji.contains(u8"🗺️")) {
+ std::cout << "String \"🗺️\" (U+1F5FA U+FE0F) not found in Basic_Emoji set" << std::endl;
+ result = 1;
+ }
+ if (basic_emoji.contains_char(U'a')) {
+ std::cout << "Character a found in Basic_Emoji set" << std::endl;
+ result = 1;
+ }
+
+ if (basic_emoji.contains(u8"aa")) {
+ std::cout << "String \"aa\" found in Basic_Emoji set" << std::endl;
+ result = 1;
+ }
+
+ if (result != 0) {
+ return result;
+ } else {
+ std::cout << "Basic_Emoji set contains appropriate characters" << std::endl;
+ }
+ ICU4XLocale locale = ICU4XLocale::create_from_string("bn").ok().value();
+ ICU4XUnicodeSetData exemplars = ICU4XUnicodeSetData::load_exemplars_main(dp, locale).ok().value();
+ if (!exemplars.contains_char(U'ব')) {
+ std::cout << "Character 'ব' not found in Bangla exemplar chars set" << std::endl;
+ result = 1;
+ }
+
+ if (!exemplars.contains(u8"ক্ষ")) {
+ std::cout << "String \"ক্ষ\" (U+0995U+09CDU+09B7) not found in Bangla exemplar chars set" << std::endl;
+ result = 1;
+ }
+ if (exemplars.contains_char(U'a')) {
+ std::cout << "Character a found in Bangla exemplar chars set" << std::endl;
+ result = 1;
+ }
+
+ if (exemplars.contains(u8"aa")) {
+ std::cout << "String \"aa\" not found in Bangla exemplar chars set" << std::endl;
+ result = 1;
+ }
+ if (result != 0) {
+ return result;
+ } else {
+ std::cout << "Bangla exemplar chars set contains appropriate characters" << std::endl;
+ }
+
+
+ ICU4XPropertyValueNameToEnumMapper mapper = ICU4XPropertyValueNameToEnumMapper::load_script(dp).ok().value();
+ int32_t script = mapper.get_strict("Brah");
+ if (script != 65) {
+ std::cout << "Expected discriminant 64 for script name `Brah`, found " << script << std::endl;
+ result = 1;
+ }
+ script = mapper.get_strict("Brahmi");
+ if (script != 65) {
+ std::cout << "Expected discriminant 64 for script name `Brahmi`, found " << script << std::endl;
+ result = 1;
+ }
+ script = mapper.get_loose("brah");
+ if (script != 65) {
+ std::cout << "Expected discriminant 64 for (loose matched) script name `brah`, found " << script << std::endl;
+ result = 1;
+ }
+ script = mapper.get_strict("Linear_Z");
+ if (script != -1) {
+ std::cout << "Expected no value for fake script name `Linear_Z`, found " << script << std::endl;
+ result = 1;
+ }
+ if (result != 0) {
+ return result;
+ } else {
+ std::cout << "Script name mapper returns correct values" << std::endl;
+ }
+
+ ICU4XGeneralCategoryNameToMaskMapper mask_mapper = ICU4XGeneralCategoryNameToMaskMapper::load(dp).ok().value();
+ int32_t mask = mask_mapper.get_strict("Lu");
+ if (mask != 0x02) {
+ std::cout << "Expected discriminant 0x02 for mask name `Lu`, found " << mask << std::endl;
+ result = 1;
+ }
+ mask = mask_mapper.get_strict("L");
+ if (mask != 0x3e) {
+ std::cout << "Expected discriminant 0x3e for mask name `Lu`, found " << mask << std::endl;
+ result = 1;
+ }
+ mask = mask_mapper.get_strict("Letter");
+ if (mask != 0x3e) {
+ std::cout << "Expected discriminant 0x3e for mask name `Letter`, found " << mask << std::endl;
+ result = 1;
+ }
+ mask = mask_mapper.get_loose("l");
+ if (mask != 0x3e) {
+ std::cout << "Expected discriminant 0x3e for mask name `l`, found " << mask << std::endl;
+ result = 1;
+ }
+ mask = mask_mapper.get_strict("letter");
+ if (mask != 0) {
+ std::cout << "Expected no mask for (strict matched) name `letter`, found " << mask << std::endl;
+ result = 1;
+ }
+ mask = mask_mapper.get_strict("EverythingLol");
+ if (mask != 0) {
+ std::cout << "Expected no mask for nonexistant name `EverythingLol`, found " << mask << std::endl;
+ result = 1;
+ }
+
+
+ if (result != 0) {
+ return result;
+ } else {
+ std::cout << "Mask name mapper returns correct values" << std::endl;
+ }
+
+
+ mask = mask_mapper.get_strict("Lu");
+ ICU4XCodePointMapData8 gc = ICU4XCodePointMapData8::load_general_category(dp).ok().value();
+ auto ranges = gc.iter_ranges_for_mask(mask);
+ auto next = ranges.next();
+ if (next.done) {
+ std::cout << "Got empty iterator!";
+ result = 1;
+ }
+ if (next.start != U'A' || next.end != U'Z') {
+ std::cout << "Expected range [" << U'A' << ", " << U'Z' << "], got range [" << next.start << ", " << next.end << "]" << std::endl;
+ result = 1;
+ }
+
+ // Test iteration to completion for a small set
+ mask = mask_mapper.get_strict("Control");
+ ranges = gc.iter_ranges_for_mask(mask);
+ next = ranges.next();
+
+ if (next.start != 0 || next.end != 0x1f) {
+ std::cout << "Expected range [0, 0x1f], got range [" << next.start << ", " << next.end << "]" << std::endl;
+ result = 1;
+ }
+
+ std::cout << "Found ranges for gc=Control:";
+ while (!next.done) {
+ std::cout << " [" << next.start << ", " << next.end << "]";
+
+ next = ranges.next();
+ }
+ std::cout << std::endl;
+
+ if (result != 0) {
+ return result;
+ } else {
+ std::cout << "Ranges iterator works" << std::endl;
+ }
+ return 0;
+}
diff --git a/intl/icu_capi/cpp/examples/segmenter/.gitignore b/intl/icu_capi/cpp/examples/segmenter/.gitignore
new file mode 100644
index 0000000000..cb34c546b3
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/segmenter/.gitignore
@@ -0,0 +1,2 @@
+a.out
+a.out.dSYM
diff --git a/intl/icu_capi/cpp/examples/segmenter/Makefile b/intl/icu_capi/cpp/examples/segmenter/Makefile
new file mode 100644
index 0000000000..57a9c06943
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/segmenter/Makefile
@@ -0,0 +1,28 @@
+# This file is part of ICU4X. For terms of use, please see the file
+# called LICENSE at the top level of the ICU4X source tree
+# (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+.DEFAULT_GOAL := test
+.PHONY: build test
+FORCE:
+
+ALL_HEADERS := $(wildcard ../../include/*.hpp) $(wildcard ../../../c/include/*.h)
+
+CXX?=g++
+
+$(ALL_HEADERS):
+
+../../../../../target/debug/libicu_capi_staticlib.a: FORCE
+ cargo build -p icu_capi_staticlib
+
+a.out: ../../../../../target/debug/libicu_capi_staticlib.a $(ALL_HEADERS) test.cpp
+ $(CXX) -std=c++17 test.cpp ../../../../../target/debug/libicu_capi_staticlib.a -ldl -lpthread -lm -g
+
+build: a.out
+
+test: build
+ ./a.out
+
+clean:
+ git clean -xf *
+ rm -f ../../../../../target/debug/libicu_capi_staticlib.a
diff --git a/intl/icu_capi/cpp/examples/segmenter/test.cpp b/intl/icu_capi/cpp/examples/segmenter/test.cpp
new file mode 100644
index 0000000000..cfe0899f76
--- /dev/null
+++ b/intl/icu_capi/cpp/examples/segmenter/test.cpp
@@ -0,0 +1,160 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+#include "../../include/ICU4XDataProvider.hpp"
+#include "../../include/ICU4XGraphemeClusterSegmenter.hpp"
+#include "../../include/ICU4XLineSegmenter.hpp"
+#include "../../include/ICU4XSentenceSegmenter.hpp"
+#include "../../include/ICU4XWordSegmenter.hpp"
+#include "../../include/ICU4XLogger.hpp"
+
+#include <iostream>
+#include <string_view>
+
+using std::cout;
+using std::endl;
+
+void print_ruler(size_t str_len) {
+ for (size_t i = 0; i < str_len; i++) {
+ if (i % 10 == 0) {
+ cout << "0";
+ } else if (i % 5 == 0) {
+ cout << "5";
+ } else {
+ cout << ".";
+ }
+ }
+ cout << endl;
+}
+
+template <typename Iterator>
+void iterate_breakpoints(Iterator& iterator) {
+ while (true) {
+ int32_t breakpoint = iterator.next();
+ if (breakpoint == -1) {
+ break;
+ }
+ cout << " " << breakpoint;
+ }
+ cout << endl;
+}
+
+template <typename Iterator>
+void iterate_word_breakpoints(Iterator& iterator) {
+ while (true) {
+ int32_t breakpoint = iterator.next();
+ if (breakpoint == -1) {
+ break;
+ }
+ cout << " " << breakpoint;
+ switch (iterator.word_type()) {
+ case ICU4XSegmenterWordType::None:
+ cout << " (none";
+ break;
+ case ICU4XSegmenterWordType::Number:
+ cout << " (number";
+ break;
+ case ICU4XSegmenterWordType::Letter:
+ cout << " (letter";
+ break;
+ default:
+ cout << " (unknown status";
+ break;
+ }
+ if (iterator.is_word_like()) {
+ cout << ", word-like";
+ }
+ cout << ")";
+ }
+ cout << endl;
+}
+
+void test_line(const std::string_view& str) {
+ const auto provider = ICU4XDataProvider::create_compiled();
+ const auto segmenter_auto =
+ ICU4XLineSegmenter::create_auto(provider).ok().value();
+ const auto segmenter_lstm =
+ ICU4XLineSegmenter::create_lstm(provider).ok().value();
+ const auto segmenter_dictionary =
+ ICU4XLineSegmenter::create_dictionary(provider).ok().value();
+
+ const ICU4XLineSegmenter* segmenters[] = {&segmenter_auto, &segmenter_lstm,
+ &segmenter_dictionary};
+ for (const auto* segmenter : segmenters) {
+ cout << "Finding line breakpoints in string:" << endl << str << endl;
+ print_ruler(str.size());
+
+ cout << "Line breakpoints:";
+ auto iterator = segmenter->segment_utf8(str);
+ iterate_breakpoints(iterator);
+ }
+}
+
+void test_grapheme(const std::string_view& str) {
+ const auto provider = ICU4XDataProvider::create_compiled();
+ const auto segmenter = ICU4XGraphemeClusterSegmenter::create(provider).ok().value();
+ cout << "Finding grapheme cluster breakpoints in string:" << endl
+ << str << endl;
+ print_ruler(str.size());
+
+ cout << "Grapheme cluster breakpoints:";
+ auto iterator = segmenter.segment_utf8(str);
+ iterate_breakpoints(iterator);
+}
+
+void test_word(const std::string_view& str) {
+ const auto provider = ICU4XDataProvider::create_compiled();
+ const auto segmenter_auto =
+ ICU4XWordSegmenter::create_auto(provider).ok().value();
+ const auto segmenter_lstm =
+ ICU4XWordSegmenter::create_lstm(provider).ok().value();
+ const auto segmenter_dictionary =
+ ICU4XWordSegmenter::create_dictionary(provider).ok().value();
+
+ const ICU4XWordSegmenter* segmenters[] = {&segmenter_auto, &segmenter_lstm,
+ &segmenter_dictionary};
+ for (const auto* segmenter : segmenters) {
+ cout << "Finding word breakpoints in string:" << endl << str << endl;
+ print_ruler(str.size());
+
+ cout << "Word breakpoints:";
+ auto iterator = segmenter->segment_utf8(str);
+ iterate_word_breakpoints(iterator);
+ }
+}
+
+void test_sentence(const std::string_view& str) {
+ const auto provider = ICU4XDataProvider::create_compiled();
+ const auto segmenter = ICU4XSentenceSegmenter::create(provider).ok().value();
+ cout << "Finding sentence breakpoints in string:" << endl
+ << str << endl;
+ print_ruler(str.size());
+
+ cout << "Sentence breakpoints:";
+ auto iterator = segmenter.segment_utf8(str);
+ iterate_breakpoints(iterator);
+}
+
+int main(int argc, char* argv[]) {
+ ICU4XLogger::init_simple_logger();
+ std::string_view str;
+ if (argc >= 2) {
+ str = argv[1];
+ } else {
+ str = "The 101 quick brown foxes jump over the lazy dog.";
+ }
+
+ test_line(str);
+ cout << endl;
+
+ test_grapheme(str);
+ cout << endl;
+
+ test_word(str);
+ cout << endl;
+
+ test_sentence(str);
+ cout << endl;
+ return 0;
+}