ICU-20121 Adding span field for FormattedList.
diff --git a/icu4c/source/i18n/listformatter.cpp b/icu4c/source/i18n/listformatter.cpp
index 5968284..6881421 100644
--- a/icu4c/source/i18n/listformatter.cpp
+++ b/icu4c/source/i18n/listformatter.cpp
@@ -420,6 +420,21 @@
if (U_FAILURE(errorCode)) {
return FormattedList(errorCode);
}
+
+ // Add span fields and sort
+ ConstrainedFieldPosition cfpos;
+ cfpos.constrainField(UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD);
+ int32_t i = 0;
+ handler.setCategory(UFIELD_CATEGORY_LIST_SPAN);
+ while (result->nextPosition(cfpos, errorCode)) {
+ handler.addAttribute(i++, cfpos.getStart(), cfpos.getLimit());
+ }
+ handler.getError(errorCode);
+ if (U_FAILURE(errorCode)) {
+ return FormattedList(errorCode);
+ }
+ result->sort();
+
return FormattedList(result.orphan());
}
#endif
diff --git a/icu4c/source/i18n/unicode/listformatter.h b/icu4c/source/i18n/unicode/listformatter.h
index b11676d..bf956ba 100644
--- a/icu4c/source/i18n/unicode/listformatter.h
+++ b/icu4c/source/i18n/unicode/listformatter.h
@@ -66,6 +66,13 @@
/**
* An immutable class containing the result of a list formatting operation.
*
+ * When calling nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the nextPosition() iterator.
+ *
* Not intended for public subclassing.
*
* @draft ICU 64
diff --git a/icu4c/source/i18n/unicode/uformattedvalue.h b/icu4c/source/i18n/unicode/uformattedvalue.h
index 362408b..1fe977f 100644
--- a/icu4c/source/i18n/unicode/uformattedvalue.h
+++ b/icu4c/source/i18n/unicode/uformattedvalue.h
@@ -80,6 +80,13 @@
#endif
/**
+ * Category for spans in a list.
+ *
+ * @draft ICU 64
+ */
+ UFIELD_CATEGORY_LIST_SPAN = 0x1000 + UFIELD_CATEGORY_LIST,
+
+ /**
* Category for spans in a date interval.
*
* @draft ICU 64
diff --git a/icu4c/source/i18n/unicode/ulistformatter.h b/icu4c/source/i18n/unicode/ulistformatter.h
index cf730bf..2afc50d 100644
--- a/icu4c/source/i18n/unicode/ulistformatter.h
+++ b/icu4c/source/i18n/unicode/ulistformatter.h
@@ -114,6 +114,13 @@
*
* You can think of this method as a cast between types.
*
+ * When calling ufmtval_nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the ufmtval_nextPosition() iterator.
+ *
* @param uresult The object containing the formatted string.
* @param ec Set if an error occurs.
* @return A UFormattedValue owned by the input object.
diff --git a/icu4c/source/test/cintltst/ulistfmttest.c b/icu4c/source/test/cintltst/ulistfmttest.c
index b89f1b3..5eb5a1e 100644
--- a/icu4c/source/test/cintltst/ulistfmttest.c
+++ b/icu4c/source/test/cintltst/ulistfmttest.c
@@ -147,11 +147,14 @@
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// field, begin index, end index
+ {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
{UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
- {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+ {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+ {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
checkMixedFormattedValue(
message,
ulistfmt_resultAsValue(fl, &ec),
@@ -175,19 +178,26 @@
assertSuccess("Formatting", &ec);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// field, begin index, end index
+ {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 1},
{UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 1},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3, 4},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6, 7},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9, 10},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 1, 3},
+ {UFIELD_CATEGORY_LIST_SPAN, 1, 3, 4},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3, 4},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 4, 6},
+ {UFIELD_CATEGORY_LIST_SPAN, 2, 6, 7},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6, 7},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 7, 9},
+ {UFIELD_CATEGORY_LIST_SPAN, 3, 9, 10},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9, 10},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 10, 12},
+ {UFIELD_CATEGORY_LIST_SPAN, 4, 12, 13},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 13, 15},
- {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+ {UFIELD_CATEGORY_LIST_SPAN, 5, 15, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+ {UFIELD_CATEGORY_LIST_SPAN, 6, 22, 23},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23}};
checkMixedFormattedValue(
message,
ulistfmt_resultAsValue(fl, &ec),
diff --git a/icu4c/source/test/intltest/listformattertest.cpp b/icu4c/source/test/intltest/listformattertest.cpp
index 239eb78..955c3d9 100644
--- a/icu4c/source/test/intltest/listformattertest.cpp
+++ b/icu4c/source/test/intltest/listformattertest.cpp
@@ -556,11 +556,14 @@
FormattedList result = fmt->formatStringsToValue(inputs, UPRV_LENGTHOF(inputs), status);
static const UFieldPositionWithCategory expectedFieldPositions[] = {
// field, begin index, end index
+ {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
{UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
- {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
{UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
- {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+ {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+ {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+ {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
checkMixedFormattedValue(
message,
result,