ICU-8451 Initial port - Region APIs from Java to C++

X-SVN-Rev: 33048
This commit is contained in:
John Emmons 2013-01-14 18:37:56 +00:00
parent 54098be451
commit 013c6db432
11 changed files with 1715 additions and 1 deletions

5
.gitattributes vendored
View File

@ -80,6 +80,9 @@ icu4c/source/extra/uconv/uconv.vcxproj -text
icu4c/source/extra/uconv/uconv.vcxproj.filters -text
icu4c/source/i18n/i18n.vcxproj -text
icu4c/source/i18n/i18n.vcxproj.filters -text
icu4c/source/i18n/region.cpp -text
icu4c/source/i18n/region_impl.h -text
icu4c/source/i18n/unicode/region.h -text
icu4c/source/io/io.vcxproj -text
icu4c/source/io/io.vcxproj.filters -text
icu4c/source/layout/layout.vcxproj -text
@ -141,6 +144,8 @@ icu4c/source/test/cintltst/cintltst.vcxproj -text
icu4c/source/test/cintltst/cintltst.vcxproj.filters -text
icu4c/source/test/intltest/intltest.vcxproj -text
icu4c/source/test/intltest/intltest.vcxproj.filters -text
icu4c/source/test/intltest/regiontst.cpp -text
icu4c/source/test/intltest/regiontst.h -text
icu4c/source/test/iotest/iotest.vcxproj -text
icu4c/source/test/iotest/iotest.vcxproj.filters -text
icu4c/source/test/letest/cletest.vcxproj -text

View File

@ -248,6 +248,7 @@
<ClCompile Include="bocsu.cpp" />
<ClCompile Include="coleitr.cpp" />
<ClCompile Include="coll.cpp" />
<ClCompile Include="region.cpp" />
<ClCompile Include="search.cpp" />
<ClCompile Include="sortkey.cpp" />
<ClCompile Include="stsearch.cpp" />
@ -537,6 +538,7 @@
</CustomBuild>
<ClInclude Include="dcfmtimp.h" />
<ClInclude Include="numsys_impl.h" />
<ClInclude Include="region_impl.h" />
<ClInclude Include="selfmtimpl.h" />
<ClInclude Include="tzgnames.h" />
<ClInclude Include="tznames_impl.h" />
@ -594,6 +596,7 @@
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
</CustomBuild>
<ClInclude Include="unicode\region.h" />
<ClInclude Include="usrchimp.h" />
<ClInclude Include="astro.h" />
<CustomBuild Include="unicode\basictz.h">

View File

@ -490,6 +490,9 @@
<Filter>formatting</Filter>
</ClCompile>
<ClCompile Include="bocsu.cpp" />
<ClCompile Include="region.cpp">
<Filter>formatting</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="bocsu.h">
@ -780,6 +783,12 @@
<ClInclude Include="selfmtimpl.h">
<Filter>formatting</Filter>
</ClInclude>
<ClInclude Include="region_impl.h">
<Filter>formatting</Filter>
</ClInclude>
<ClInclude Include="unicode\region.h">
<Filter>formatting</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="i18n.rc">

View File

@ -0,0 +1,617 @@
/*
*******************************************************************************
* Copyright (C) 2013, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
*
* File REGION.CPP
*
* Modification History:*
* Date Name Description
* 01/15/13 Emmons Original Port from ICU4J
********************************************************************************
*/
/**
* \file
* \brief C++ API: Region classes (territory containment)
*/
#include "unicode/region.h"
#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "unicode/ures.h"
#include "unicode/decimfmt.h"
#include "cstring.h"
#include "uhash.h"
#include "uresimp.h"
#include "region_impl.h"
#if !UCONFIG_NO_FORMATTING
U_NAMESPACE_BEGIN
static UBool regionDataIsLoaded = false;
static UVector* regions = NULL;
static UVector* availableRegions[URGN_LIMIT];
static UHashtable *regionAliases;
static UHashtable *regionIDMap;
static UHashtable *numericCodeMap;
static UnicodeString UNKNOWN_REGION_ID = UNICODE_STRING_SIMPLE("ZZ");
static UnicodeString OUTLYING_OCEANIA_REGION_ID = UNICODE_STRING_SIMPLE("QO");
static UnicodeString WORLD_ID = UNICODE_STRING_SIMPLE("001");
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Region)
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration)
void addRegion( Region *r ) {
UErrorCode status = U_ZERO_ERROR;
if ( regions == NULL ) {
regions = new UVector(NULL, NULL, status);
}
regions->addElement(r,status);
}
void addAvailableRegion( const Region *r , URegionType type) {
UErrorCode status = U_ZERO_ERROR;
if ( availableRegions[type] == NULL ) {
availableRegions[type] = new UVector(NULL, uhash_compareChars, status);
}
availableRegions[type]->addElement((void *)r->getRegionCode(),status);
}
/*
* Initializes the region data from the ICU resource bundles. The region data
* contains the basic relationships such as which regions are known, what the numeric
* codes are, any known aliases, and the territory containment data.
*
* If the region data has already loaded, then this method simply returns without doing
* anything meaningful.
*/
void Region::loadRegionData() {
if (regionDataIsLoaded) {
return;
}
UErrorCode status = U_ZERO_ERROR;
UResourceBundle* regionCodes = NULL;
UResourceBundle* territoryAlias = NULL;
UResourceBundle* codeMappings = NULL;
UResourceBundle* worldContainment = NULL;
UResourceBundle* territoryContainment = NULL;
UResourceBundle* groupingContainment = NULL;
DecimalFormat *df = new DecimalFormat(status);
df->setParseIntegerOnly(TRUE);
regionAliases = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status);
regionIDMap = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status);
numericCodeMap = uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status);
UResourceBundle *rb = ures_openDirect(NULL,"metadata",&status);
regionCodes = ures_getByKey(rb,"regionCodes",NULL,&status);
territoryAlias = ures_getByKey(rb,"territoryAlias",NULL,&status);
UResourceBundle *rb2 = ures_openDirect(NULL,"supplementalData",&status);
codeMappings = ures_getByKey(rb2,"codeMappings",NULL,&status);
territoryContainment = ures_getByKey(rb2,"territoryContainment",NULL,&status);
worldContainment = ures_getByKey(territoryContainment,"001",NULL,&status);
groupingContainment = ures_getByKey(territoryContainment,"grouping",NULL,&status);
UVector *continents = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
while ( ures_hasNext(worldContainment) ) {
UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeString(worldContainment,NULL,&status));
continents->addElement(continentName,status);
}
UVector *groupings = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
while ( ures_hasNext(groupingContainment) ) {
UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeString(groupingContainment,NULL,&status));
groupings->addElement(groupingName,status);
}
while ( ures_hasNext(regionCodes) ) {
UnicodeString regionID = ures_getNextUnicodeString(regionCodes,NULL,&status);
Region *r = new Region();
r->idStr = regionID;
r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV);
r->type = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known.
uhash_put(regionIDMap,(void *)&(r->idStr),(void *)r,&status);
Formattable result;
UErrorCode ps = U_ZERO_ERROR;
df->parse(r->idStr,result,ps);
if ( U_SUCCESS(ps) ) {
r->code = result.getLong(); // Convert string to number
uhash_iput(numericCodeMap,r->code,(void *)r,&status);
r->type = URGN_SUBCONTINENT;
} else {
r->code = Region::UNDEFINED_NUMERIC_CODE;
}
addRegion(r);
}
// Process the territory aliases
int32_t territoryAliasSize = ures_getSize(territoryAlias);
while ( ures_hasNext(territoryAlias) ) {
UResourceBundle *res = ures_getNextResource(territoryAlias,NULL,&status);
const char *aliasFrom = ures_getKey(res);
UnicodeString* aliasFromStr = new UnicodeString(aliasFrom);
UnicodeString aliasTo = ures_getUnicodeString(res,&status);
Region *aliasToRegion = (Region *) uhash_get(regionIDMap,&aliasTo);
Region *aliasFromRegion = (Region *)uhash_get(regionIDMap,aliasFromStr);
if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is just an alias from some string to a region
uhash_put(regionAliases,(void *)aliasFromStr, (void *)aliasToRegion,&status);
} else {
if ( aliasFromRegion == NULL ) { // Deprecated region code not in the master codes list - so need to create a deprecated region for it.
aliasFromRegion = new Region();
aliasFromRegion->idStr.setTo(*aliasFromStr);
aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length(),aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV);
uhash_put(regionIDMap,(void *)&(aliasFromRegion->idStr),(void *)aliasFromRegion,&status);
Formattable result;
UErrorCode ps = U_ZERO_ERROR;
df->parse(aliasFromRegion->idStr,result,ps);
if ( U_SUCCESS(ps) ) {
aliasFromRegion->code = result.getLong(); // Convert string to number
uhash_iput(numericCodeMap,aliasFromRegion->code,(void *)aliasFromRegion,&status);
} else {
aliasFromRegion->code = Region::UNDEFINED_NUMERIC_CODE;
}
aliasFromRegion->type = URGN_DEPRECATED;
addRegion(aliasFromRegion);
} else {
aliasFromRegion->type = URGN_DEPRECATED;
}
delete aliasFromStr;
aliasFromRegion->preferredValues = new UVector(NULL, uhash_compareChars, status);
UnicodeString currentRegion;
currentRegion.remove();
for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) {
if ( aliasTo.charAt(i) != 0x0020 ) {
currentRegion.append(aliasTo.charAt(i));
}
if ( aliasTo.charAt(i) == 0x0020 || i+1 == aliasTo.length() ) {
Region *target = (Region *)uhash_get(regionIDMap,(void *)&currentRegion);
if (target) {
aliasFromRegion->preferredValues->addElement((void *)target->id,status);
}
currentRegion.remove();
}
}
}
}
// Process the code mappings - This will allow us to assign numeric codes to most of the territories.
while ( ures_hasNext(codeMappings) ) {
UResourceBundle *mapping = ures_getNextResource(codeMappings,NULL,&status);
if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) {
UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0,&status);
UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mapping,1,&status);
UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapping,2,&status);
Region *r = (Region *)uhash_get(regionIDMap,(void *)&codeMappingID);
if ( r ) {
Formattable result;
UErrorCode ps = U_ZERO_ERROR;
df->parse(codeMappingNumber,result,ps);
if ( U_SUCCESS(ps) ) {
r->code = result.getLong(); // Convert string to number
uhash_iput(numericCodeMap,r->code,(void *)r,&status);
}
UnicodeString *code3 = new UnicodeString(codeMapping3Letter);
uhash_put(regionAliases,(void *)code3, (void *)r,&status);
}
}
}
// Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPINGS
Region *r;
r = (Region *) uhash_get(regionIDMap,(void *)&WORLD_ID);
if ( r ) {
r->type = URGN_WORLD;
}
r = (Region *) uhash_get(regionIDMap,(void *)&UNKNOWN_REGION_ID);
if ( r ) {
r->type = URGN_UNKNOWN;
}
for ( int32_t i = 0 ; i < continents->size() ; i++ ) {
r = (Region *) uhash_get(regionIDMap,(void *)continents->elementAt(i));
if ( r ) {
r->type = URGN_CONTINENT;
}
}
delete continents;
for ( int32_t i = 0 ; i < groupings->size() ; i++ ) {
r = (Region *) uhash_get(regionIDMap,(void *)groupings->elementAt(i));
if ( r ) {
r->type = URGN_GROUPING;
}
}
delete groupings;
// Special case: The region code "QO" (Outlying Oceania) is a subcontinent code added by CLDR
// even though it looks like a territory code. Need to handle it here.
r = (Region *) uhash_get(regionIDMap,(void *)&OUTLYING_OCEANIA_REGION_ID);
if ( r ) {
r->type = URGN_SUBCONTINENT;
}
// Load territory containment info from the supplemental data.
while ( ures_hasNext(territoryContainment) ) {
UResourceBundle *mapping = ures_getNextResource(territoryContainment,NULL,&status);
const char *parent = ures_getKey(mapping);
UnicodeString parentStr = UnicodeString(parent);
Region *parentRegion = (Region *) uhash_get(regionIDMap,(void *)&parentStr);
for ( int j = 0 ; j < ures_getSize(mapping); j++ ) {
UnicodeString child = ures_getUnicodeStringByIndex(mapping,j,&status);
Region *childRegion = (Region *) uhash_get(regionIDMap,(void *)&child);
if ( parentRegion != NULL && childRegion != NULL ) {
// Add the child region to the set of regions contained by the parent
if (parentRegion->containedRegions == NULL) {
parentRegion->containedRegions = new UVector(NULL, uhash_compareChars, status);
}
parentRegion->containedRegions->addElement((void *)childRegion->id,status);
// Set the parent region to be the containing region of the child.
// Regions of type GROUPING can't be set as the parent, since another region
// such as a SUBCONTINENT, CONTINENT, or WORLD must always be the parent.
if ( parentRegion->type != URGN_GROUPING) {
childRegion->containingRegion = parentRegion;
}
}
}
}
// Create the availableRegions lists
for ( int32_t i = 0 ; i < regions->size() ; i++ ) {
Region *ar = (Region *)regions->elementAt(i);
addAvailableRegion(ar,ar->type);
}
regionDataIsLoaded = true;
ures_close(territoryContainment);
ures_close(worldContainment);
ures_close(groupingContainment);
ures_close(codeMappings);
ures_close(rb2);
ures_close(territoryAlias);
ures_close(regionCodes);
ures_close(rb);
delete df;
}
/*
* Default constructor. Use factory methods only.
* @internal
*/
Region::Region () {
idStr.remove();
code = UNDEFINED_NUMERIC_CODE;
type = URGN_UNKNOWN;
containingRegion = NULL;
containedRegions = NULL;
preferredValues = NULL;
}
/**
* Returns true if the two regions are equal.
*/
UBool U_EXPORT2
Region::operator==(const Region &that) const {
return (idStr == that.idStr);
}
/**
* Returns true if the two regions are NOT equal; that is, if operator ==() returns false.
*/
UBool U_EXPORT2
Region::operator!=(const Region &that) const {
return (idStr != that.idStr);
}
/**
* Returns a pointer to a Region using the given region code. The region code can be either 2-letter ISO code,
* 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code as defined by the LDML specification.
* The identifier will be canonicalized internally using the supplemental metadata as defined in the CLDR.
* If the region code is NULL or not recognized, the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR )
*/
const Region* U_EXPORT2
Region::getInstance(const char *region_code, UErrorCode &status) {
if ( !region_code ) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
loadRegionData();
UnicodeString regionCodeString = UnicodeString(region_code);
Region *r = (Region *)uhash_get(regionIDMap,(void *)&regionCodeString);
if ( !r ) {
r = (Region *)uhash_get(regionAliases,(void *)&regionCodeString);
}
if ( !r ) { // Unknown region code
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) {
StringEnumeration *pv = r->getPreferredValues();
pv->reset(status);
const UnicodeString *ustr = pv->snext(status);
r = (Region *)uhash_get(regionIDMap,(void *)ustr);
}
return r;
}
/**
* Returns a pointer to a Region using the given numeric region code. If the numeric region code is not recognized,
* the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ).
*/
const Region * U_EXPORT2
Region::getInstance (int32_t code, UErrorCode &status) {
loadRegionData();
Region *r = (Region *)uhash_iget(numericCodeMap,code);
if ( !r ) { // Just in case there's an alias that's numeric, try to find it.
UErrorCode fs = U_ZERO_ERROR;
UnicodeString pat = UNICODE_STRING_SIMPLE("00#");
DecimalFormat *df = new DecimalFormat(pat,fs);
UnicodeString id;
id.remove();
df->format(code,id);
delete df;
r = (Region *)uhash_get(regionAliases,&id);
}
if ( !r ) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) {
StringEnumeration *pv = r->getPreferredValues();
pv->reset(status);
const UnicodeString *ustr = pv->snext(status);
r = (Region *)uhash_get(regionIDMap,(void *)ustr);
}
return r;
}
/**
* Returns an enumeration over the IDs of all known regions that match the given type.
*/
StringEnumeration * U_EXPORT2
Region::getAvailable(URegionType type) {
loadRegionData();
UErrorCode status = U_ZERO_ERROR;
return new RegionNameEnumeration(availableRegions[type],status);
return NULL;
}
/**
* Returns a pointer to the region that contains this region. Returns NULL if this region is code "001" (World)
* or "ZZ" (Unknown region). For example, calling this method with region "IT" (Italy) returns the
* region "039" (Southern Europe).
*/
const Region * U_EXPORT2
Region::getContainingRegion() const {
loadRegionData();
return containingRegion;
}
/**
* Return a pointer to the region that geographically contains this region and matches the given type,
* moving multiple steps up the containment chain if necessary. Returns NULL if no containing region can be found
* that matches the given type. Note: The URegionTypes = "URGN_GROUPING", "URGN_DEPRECATED", or "URGN_UNKNOWN"
* are not appropriate for use in this API. NULL will be returned in this case. For example, calling this method
* with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" ( Europe ).
*/
const Region* U_EXPORT2
Region::getContainingRegion(URegionType type) const {
loadRegionData();
if ( containingRegion == NULL ) {
return NULL;
}
if ( containingRegion->type == type ) {
return containingRegion;
} else {
return containingRegion->getContainingRegion(type);
}
}
/**
* Return an enumeration over the IDs of all the regions that are immediate children of this region in the
* region hierarchy. These returned regions could be either macro regions, territories, or a mixture of the two,
* depending on the containment data as defined in CLDR. This API may return NULL if this region doesn't have
* any sub-regions. For example, calling this method with region "150" (Europe) returns an enumeration containing
* the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) - "154" (Northern Europe)
* and "155" (Western Europe).
*/
StringEnumeration * U_EXPORT2
Region::getContainedRegions() const {
loadRegionData();
UErrorCode status = U_ZERO_ERROR;
return new RegionNameEnumeration(containedRegions,status);
}
/**
* Returns an enumeration over the IDs of all the regions that are children of this region anywhere in the region
* hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any
* sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type
* "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. )
*/
StringEnumeration * U_EXPORT2
Region::getContainedRegions( URegionType type ) const {
loadRegionData();
UErrorCode status = U_ZERO_ERROR;
UVector *result = new UVector(uprv_deleteUObject, uhash_compareChars, status);
StringEnumeration *cr = getContainedRegions();
for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) {
const char *id = cr->next(NULL,status);
const Region *r = Region::getInstance(id,status);
if ( r->getType() == type ) {
result->addElement((void *)r->id,status);
} else {
StringEnumeration *children = r->getContainedRegions(type);
for ( int32_t j = 0 ; j < children->count(status) ; j++ ) {
const char *id2 = children->next(NULL,status);
const Region *r2 = Region::getInstance(id2,status);
result->addElement((void *)r2->id,status);
}
}
}
return new RegionNameEnumeration(result,status);
}
/**
* Returns true if this region contains the supplied other region anywhere in the region hierarchy.
*/
UBool U_EXPORT2
Region::contains(const Region &other) const {
loadRegionData();
if (!containedRegions) {
return FALSE;
}
if (containedRegions->contains((void *)other.id)) {
return TRUE;
} else {
for ( int32_t i = 0 ; i < containedRegions->size() ; i++ ) {
UErrorCode status = U_ZERO_ERROR;
const Region *cr = Region::getInstance((const char *)containedRegions->elementAt(i),status);
if ( cr && cr->contains(other) ) {
return TRUE;
}
}
}
return FALSE;
}
/**
* For deprecated regions, return an enumeration over the IDs of the regions that are the preferred replacement
* regions for this region. Returns NULL for a non-deprecated region. For example, calling this method with region
* "SU" (Soviet Union) would return a list of the regions containing "RU" (Russia), "AM" (Armenia), "AZ" (Azerbaijan), etc...
*/
StringEnumeration * U_EXPORT2
Region::getPreferredValues() const {
loadRegionData();
UErrorCode status = U_ZERO_ERROR;
if ( type == URGN_DEPRECATED ) {
return new RegionNameEnumeration(preferredValues,status);
} else {
return NULL;
}
}
/**
* Return this region's canonical region code.
*/
const char * U_EXPORT2
Region::getRegionCode() const {
return id;
}
/**
* Return this region's numeric code. Returns UNDEFINED_NUMERIC_CODE (-1) if the given region does not have a numeric code assigned to it.
*/
int32_t U_EXPORT2
Region::getNumericCode() const {
return code;
}
/**
* Returns the region type of this region.
*/
URegionType U_EXPORT2
Region::getType() const {
return type;
}
RegionNameEnumeration::RegionNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) {
pos=0;
fRegionNames = fNameList;
}
const char *
RegionNameEnumeration::next(int32_t *resultLength, UErrorCode& status) {
if (U_SUCCESS(status) && pos < fRegionNames->size()) {
if (resultLength != NULL) {
*resultLength = uprv_strlen((const char *)fRegionNames->elementAt(pos));
}
return (const char *)fRegionNames->elementAt(pos++);
}
return NULL;
}
const UnicodeString*
RegionNameEnumeration::snext(UErrorCode& status) {
int32_t resultLength=0;
const char *s=next(&resultLength, status);
return setChars(s, resultLength, status);
}
void
RegionNameEnumeration::reset(UErrorCode& /*status*/) {
pos=0;
}
int32_t
RegionNameEnumeration::count(UErrorCode& /*status*/) const {
return (fRegionNames==NULL) ? 0 : fRegionNames->size();
}
RegionNameEnumeration::~RegionNameEnumeration() {
delete fRegionNames;
}
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View File

@ -0,0 +1,44 @@
/*
*******************************************************************************
* Copyright (C) 2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* File REGION_IMPL.H
*
*******************************************************************************
*/
#ifndef __REGION_IMPL_H__
#define __REGION_IMPL_H__
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "uvector.h"
#include "unicode/strenum.h"
U_NAMESPACE_BEGIN
class RegionNameEnumeration : public StringEnumeration {
public:
RegionNameEnumeration(UVector *fNameList, UErrorCode& status);
virtual ~RegionNameEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const;
virtual const char *next(int32_t *resultLength, UErrorCode& status);
virtual const UnicodeString* snext(UErrorCode& status);
virtual void reset(UErrorCode& status);
virtual int32_t count(UErrorCode& status) const;
private:
int32_t pos;
UVector *fRegionNames;
};
U_NAMESPACE_END
#endif
#endif

View File

@ -0,0 +1,290 @@
/*
*******************************************************************************
* Copyright (C) 2013, International Business Machines Corporation *
* All Rights Reserved. *
*******************************************************************************
*/
#ifndef REGION_H
#define REGION_H
/**
* \file
* \brief C++ API: Region classes (territory containment)
*/
#include "unicode/utypes.h"
typedef enum URegionType {
/**
* Type representing the unknown region.
* @draft ICU 51
*/
URGN_UNKNOWN,
/**
* Type representing a territory.
* @draft ICU 51
*/
URGN_TERRITORY,
/**
* Type representing the whole world.
* @draft ICU 51
*/
URGN_WORLD,
/**
* Type representing a continent.
* @draft ICU 51
*/
URGN_CONTINENT,
/**
* Type representing a sub-continent.
* @draft ICU 51
*/
URGN_SUBCONTINENT,
/**
* Type representing a grouping of territories that is not to be used in
* the normal WORLD/CONTINENT/SUBCONTINENT/TERRITORY containment tree.
* @draft ICU 51
*/
URGN_GROUPING,
/**
* Type representing a region whose code has been deprecated, usually
* due to a country splitting into multiple territories or changing its name.
* @draft ICU 51
*/
URGN_DEPRECATED,
/**
* Maximum value for this unumeration.
* @draft ICU 51
*/
URGN_LIMIT
} URegionType;
#if !UCONFIG_NO_FORMATTING
#include "unicode/uobject.h"
#include "unicode/uniset.h"
#include "unicode/unistr.h"
#include "unicode/strenum.h"
U_NAMESPACE_BEGIN
/**
* <code>Region</code> is the class representing a Unicode Region Code, also known as a
* Unicode Region Subtag, which is defined based upon the BCP 47 standard. We often think of
* "regions" as "countries" when defining the characteristics of a locale. Region codes There are different
* types of region codes that are important to distinguish.
* <p>
* Macroregion - A code for a "macro geographical (continental) region, geographical sub-region, or
* selected economic and other grouping" as defined in
* UN M.49 (http://unstats.un.org/unsd/methods/m49/m49regin.htm).
* These are typically 3-digit codes, but contain some 2-letter codes, such as the LDML code QO
* added for Outlying Oceania. Not all UNM.49 codes are defined in LDML, but most of them are.
* Macroregions are represented in ICU by one of three region types: WORLD ( region code 001 ),
* CONTINENTS ( regions contained directly by WORLD ), and SUBCONTINENTS ( things contained directly
* by a continent ).
* <p>
* TERRITORY - A Region that is not a Macroregion. These are typically codes for countries, but also
* include areas that are not separate countries, such as the code "AQ" for Antarctica or the code
* "HK" for Hong Kong (SAR China). Overseas dependencies of countries may or may not have separate
* codes. The codes are typically 2-letter codes aligned with the ISO 3166 standard, but BCP47 allows
* for the use of 3-digit codes in the future.
* <p>
* UNKNOWN - The code ZZ is defined by Unicode LDML for use to indicate that the Region is unknown,
* or that the value supplied as a region was invalid.
* <p>
* DEPRECATED - Region codes that have been defined in the past but are no longer in modern usage,
* usually due to a country splitting into multiple territories or changing its name.
* <p>
* GROUPING - A widely understood grouping of territories that has a well defined membership such
* that a region code has been assigned for it. Some of these are UNM.49 codes that do't fall into
* the world/continent/sub-continent hierarchy, while others are just well known groupings that have
* their own region code. Region "EU" (European Union) is one such region code that is a grouping.
* Groupings will never be returned by the getContainingRegion() API, since a different type of region
* ( WORLD, CONTINENT, or SUBCONTINENT ) will always be the containing region instead.
*
* @author John Emmons
* @draft ICU 51
*/
class U_I18N_API Region : public UObject {
public:
/**
* URegionType is an enumeration defining the different types of regions. Current possible
* values are URGN_WORLD, URGN_CONTINENT, URGN_SUBCONTINENT, URGN_TERRITORY, URGN_GROUPING,
* URGN_DEPRECATED, and URGN_UNKNOWN.
*
* @draft ICU 51
*/
static const int32_t UNDEFINED_NUMERIC_CODE = -1;
/**
* Default Constructor.
*
* @draft ICU 51
*/
Region();
/**
* Returns true if the two regions are equal.
* @draft ICU 51
*/
UBool operator==(const Region &that) const;
/**
* Returns true if the two regions are NOT equal; that is, if operator ==() returns false.
* @draft ICU 51
*/
UBool operator!=(const Region &that) const;
/**
* Returns a pointer to a Region using the given region code. The region code can be either 2-letter ISO code,
* 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code as defined by the LDML specification.
* The identifier will be canonicalized internally using the supplemental metadata as defined in the CLDR.
* If the region code is NULL or not recognized, the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR )
* @draft ICU 51
*/
static const Region *getInstance(const char *region_code, UErrorCode &status);
/**
* Returns a pointer to a Region using the given numeric region code. If the numeric region code is not recognized,
* the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ).
* @draft ICU 51
*/
static const Region *getInstance (int32_t code, UErrorCode &status);
/**
* Returns an enumeration over the IDs of all known regions that match the given type.
* @draft ICU 51
*/
static StringEnumeration *getAvailable(URegionType type);
/**
* Returns a pointer to the region that contains this region. Returns NULL if this region is code "001" (World)
* or "ZZ" (Unknown region). For example, calling this method with region "IT" (Italy) returns the
* region "039" (Southern Europe).
* @draft ICU 51
*/
const Region *getContainingRegion() const;
/**
* Return a pointer to the region that geographically contains this region and matches the given type,
* moving multiple steps up the containment chain if necessary. Returns NULL if no containing region can be found
* that matches the given type. Note: The URegionTypes = "URGN_GROUPING", "URGN_DEPRECATED", or "URGN_UNKNOWN"
* are not appropriate for use in this API. NULL will be returned in this case. For example, calling this method
* with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" ( Europe ).
* @draft ICU 51
*/
const Region* getContainingRegion(URegionType type) const;
/**
* Return an enumeration over the IDs of all the regions that are immediate children of this region in the
* region hierarchy. These returned regions could be either macro regions, territories, or a mixture of the two,
* depending on the containment data as defined in CLDR. This API may return NULL if this region doesn't have
* any sub-regions. For example, calling this method with region "150" (Europe) returns an enumeration containing
* the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) - "154" (Northern Europe)
* and "155" (Western Europe).
* @draft ICU 51
*/
StringEnumeration *getContainedRegions() const;
/**
* Returns an enumeration over the IDs of all the regions that are children of this region anywhere in the region
* hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any
* sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type
* "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. )
* @draft ICU 51
*/
StringEnumeration *getContainedRegions( URegionType type ) const;
/**
* Returns true if this region contains the supplied other region anywhere in the region hierarchy.
* @draft ICU 51
*/
UBool contains(const Region &other) const;
/**
* For deprecated regions, return an enumeration over the IDs of the regions that are the preferred replacement
* regions for this region. Returns null for a non-deprecated region. For example, calling this method with region
* "SU" (Soviet Union) would return a list of the regions containing "RU" (Russia), "AM" (Armenia), "AZ" (Azerbaijan), etc...
* @draft ICU 51
*/
StringEnumeration *getPreferredValues() const;
/**
* Return this region's canonical region code.
* @draft ICU 51
*/
const char *getRegionCode() const;
/**
* Return this region's numeric code. Returns UNDEFINED_NUMERIC_CODE (-1) if the given region does not have a numeric code assigned to it.
* @draft ICU 51
*/
int32_t getNumericCode() const;
/**
* Returns the region type of this region.
* @draft ICU 51
*/
URegionType getType() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @stable ICU 4.2
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @stable ICU 4.2
*/
virtual UClassID getDynamicClassID() const;
private:
char id[4];
UnicodeString idStr;
int32_t code;
URegionType type;
Region *containingRegion;
UVector *containedRegions;
UVector *preferredValues;
/*
* Initializes the region data from the ICU resource bundles. The region data
* contains the basic relationships such as which regions are known, what the numeric
* codes are, any known aliases, and the territory containment data.
*
* If the region data has already loaded, then this method simply returns without doing
* anything meaningful.
* @internal
*/
static void loadRegionData();
};
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif // REGION_H
//eof

View File

@ -225,6 +225,7 @@
<ItemGroup>
<ClCompile Include="bytestrietest.cpp" />
<ClCompile Include="colldata.cpp" />
<ClCompile Include="regiontst.cpp" />
<ClCompile Include="ucharstrietest.cpp" />
<ClCompile Include="itrbbi.cpp" />
<ClCompile Include="rbbiapts.cpp" />
@ -415,6 +416,7 @@
<ClInclude Include="lcukocol.h" />
<ClInclude Include="mnkytst.h" />
<ClInclude Include="regcoll.h" />
<ClInclude Include="regiontst.h" />
<ClInclude Include="srchtest.h" />
<ClInclude Include="ssearch.h" />
<ClInclude Include="svccoll.h" />

View File

@ -454,6 +454,9 @@
<ClCompile Include="colldata.cpp">
<Filter>collation</Filter>
</ClCompile>
<ClCompile Include="regiontst.cpp">
<Filter>formatting</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="itrbbi.h">
@ -826,5 +829,8 @@
<ClInclude Include="colldata.h">
<Filter>collation</Filter>
</ClInclude>
<ClInclude Include="regiontst.h">
<Filter>formatting</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2012, International Business Machines
* Copyright (c) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************/
@ -57,6 +57,7 @@
#include "locnmtst.h" // LocaleDisplayNamesTest
#include "dcfmtest.h" // DecimalFormatTest
#include "listformattertest.h" // ListFormatterTest
#include "regiontst.h" // RegionTest
extern IntlTest *createCompactDecimalFormatTest();
extern IntlTest *createGenderInfoTest();
@ -155,6 +156,7 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
callTest(*test, par);
}
break;
TESTCLASS(45,RegionTest);
default: name = ""; break; //needed to end loop
}
if (exec) {

View File

@ -0,0 +1,689 @@
/***********************************************************************
* COPYRIGHT:
* Copyright (c) 2013, International Business Machines Corporation
* and others. All Rights Reserved.
***********************************************************************/
/***********************************************************************
* This testcase ported from ICU4J ( RegionTest.java ) to ICU4C *
* Try to keep them in sync if at all possible...! *
***********************************************************************/
#include "unicode/utypes.h"
#include "cstring.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/region.h"
#include "regiontst.h"
typedef struct KnownRegion {
const char *code;
int32_t numeric;
const char *parent;
URegionType type;
const char *containingContinent;
} KnownRegion;
#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
static KnownRegion knownRegions[] = {
// Code, Num, Parent, Type, Containing Continent
{ "TP" , 626, "035", URGN_TERRITORY, "142" },
{ "001", 1, NULL , URGN_WORLD, NULL },
{ "002", 2, "001", URGN_CONTINENT, NULL },
{ "003", 3, NULL, URGN_GROUPING, NULL },
{ "005", 5, "019", URGN_SUBCONTINENT, "019" },
{ "009", 9, "001", URGN_CONTINENT, NULL},
{ "011", 11, "002", URGN_SUBCONTINENT, "002" },
{ "013", 13, "019", URGN_SUBCONTINENT, "019" },
{ "014", 14, "002", URGN_SUBCONTINENT, "002" },
{ "015", 15, "002", URGN_SUBCONTINENT, "002" },
{ "017", 17, "002", URGN_SUBCONTINENT, "002" },
{ "018", 18, "002", URGN_SUBCONTINENT, "002" },
{ "019", 19, "001", URGN_CONTINENT, NULL },
{ "021", 21, "019", URGN_SUBCONTINENT, "019" },
{ "029", 29, "019", URGN_SUBCONTINENT, "019" },
{ "030", 30, "142", URGN_SUBCONTINENT, "142" },
{ "034", 34, "142", URGN_SUBCONTINENT, "142" },
{ "035", 35, "142", URGN_SUBCONTINENT, "142" },
{ "039", 39, "150", URGN_SUBCONTINENT, "150"},
{ "053", 53, "009", URGN_SUBCONTINENT, "009" },
{ "054", 54, "009", URGN_SUBCONTINENT, "009" },
{ "057", 57, "009", URGN_SUBCONTINENT, "009" },
{ "061", 61, "009", URGN_SUBCONTINENT, "009" },
{ "142", 142, "001", URGN_CONTINENT, NULL },
{ "143", 143, "142", URGN_SUBCONTINENT, "142" },
{ "145", 145, "142", URGN_SUBCONTINENT, "142" },
{ "150", 150, "001", URGN_CONTINENT, NULL },
{ "151", 151, "150", URGN_SUBCONTINENT, "150" },
{ "154", 154, "150", URGN_SUBCONTINENT, "150" },
{ "155", 155, "150", URGN_SUBCONTINENT, "150" },
{ "419", 419, NULL, URGN_GROUPING , NULL},
{ "AC" , -1, "QO" , URGN_TERRITORY, "009" },
{ "AD" , 20, "039", URGN_TERRITORY, "150" },
{ "AE" , 784, "145", URGN_TERRITORY, "142" },
{ "AF" , 4, "034", URGN_TERRITORY, "142" },
{ "AG" , 28, "029", URGN_TERRITORY, "019" },
{ "AI" , 660, "029", URGN_TERRITORY, "019" },
{ "AL" , 8, "039", URGN_TERRITORY, "150" },
{ "AM" , 51, "145", URGN_TERRITORY, "142" },
{ "AN" , 530, NULL, URGN_DEPRECATED, NULL },
{ "AO" , 24, "017", URGN_TERRITORY, "002" },
{ "AQ" , 10, "QO" , URGN_TERRITORY, "009" },
{ "AR" , 32, "005", URGN_TERRITORY, "019" },
{ "AS" , 16, "061", URGN_TERRITORY, "009" },
{ "AT" , 40, "155", URGN_TERRITORY, "150" },
{ "AU" , 36, "053", URGN_TERRITORY, "009" },
{ "AW" , 533, "029", URGN_TERRITORY, "019" },
{ "AX" , 248, "154", URGN_TERRITORY, "150" },
{ "AZ" , 31, "145", URGN_TERRITORY, "142" },
{ "BA" , 70, "039", URGN_TERRITORY, "150" },
{ "BB" , 52, "029", URGN_TERRITORY, "019" },
{ "BD" , 50, "034", URGN_TERRITORY, "142" },
{ "BE" , 56, "155", URGN_TERRITORY, "150" },
{ "BF" , 854, "011", URGN_TERRITORY, "002" },
{ "BG" , 100, "151", URGN_TERRITORY, "150" },
{ "BH" , 48, "145", URGN_TERRITORY, "142" },
{ "BI" , 108, "014", URGN_TERRITORY, "002" },
{ "BJ" , 204, "011", URGN_TERRITORY, "002" },
{ "BL" , 652, "029", URGN_TERRITORY, "019" },
{ "BM" , 60, "021", URGN_TERRITORY, "019" },
{ "BN" , 96, "035", URGN_TERRITORY, "142" },
{ "BO" , 68, "005", URGN_TERRITORY, "019" },
{ "BQ" , 535, "029", URGN_TERRITORY, "019" },
{ "BR" , 76, "005", URGN_TERRITORY, "019" },
{ "BS" , 44, "029", URGN_TERRITORY, "019" },
{ "BT" , 64, "034", URGN_TERRITORY, "142" },
{ "BU" , 104, "035", URGN_TERRITORY, "142" },
{ "BV" , 74, "QO" , URGN_TERRITORY, "009" },
{ "BW" , 72, "018", URGN_TERRITORY, "002" },
{ "BY" , 112, "151", URGN_TERRITORY, "150" },
{ "BZ" , 84, "013", URGN_TERRITORY, "019" },
{ "CA" , 124, "021", URGN_TERRITORY, "019" },
{ "CC" , 166, "QO" , URGN_TERRITORY, "009" },
{ "CD" , 180, "017", URGN_TERRITORY, "002" },
{ "CF" , 140, "017", URGN_TERRITORY, "002" },
{ "CG" , 178, "017", URGN_TERRITORY, "002" },
{ "CH" , 756, "155", URGN_TERRITORY, "150" },
{ "CI" , 384, "011", URGN_TERRITORY, "002" },
{ "CK" , 184, "061", URGN_TERRITORY, "009" },
{ "CL" , 152, "005", URGN_TERRITORY, "019" },
{ "CM" , 120, "017", URGN_TERRITORY, "002" },
{ "CN" , 156, "030", URGN_TERRITORY, "142" },
{ "CO" , 170, "005", URGN_TERRITORY, "019" },
{ "CP" , -1 , "QO" , URGN_TERRITORY, "009" },
{ "CR" , 188, "013", URGN_TERRITORY, "019" },
{ "CU" , 192, "029", URGN_TERRITORY, "019" },
{ "CV" , 132, "011", URGN_TERRITORY, "002" },
{ "CW" , 531, "029", URGN_TERRITORY, "019" },
{ "CX" , 162, "QO" , URGN_TERRITORY, "009" },
{ "CY" , 196, "145", URGN_TERRITORY, "142" },
{ "CZ" , 203, "151", URGN_TERRITORY, "150" },
{ "DD" , 276, "155", URGN_TERRITORY, "150" },
{ "DE" , 276, "155", URGN_TERRITORY, "150" },
{ "DG" , -1 , "QO" , URGN_TERRITORY, "009" },
{ "DJ" , 262, "014", URGN_TERRITORY, "002" },
{ "DK" , 208, "154", URGN_TERRITORY, "150" },
{ "DM" , 212, "029", URGN_TERRITORY, "019" },
{ "DO" , 214, "029", URGN_TERRITORY, "019" },
{ "DZ" , 12, "015", URGN_TERRITORY, "002" },
{ "EA" , -1, "015", URGN_TERRITORY, "002" },
{ "EC" , 218, "005", URGN_TERRITORY, "019" },
{ "EE" , 233, "154", URGN_TERRITORY, "150" },
{ "EG" , 818, "015", URGN_TERRITORY, "002" },
{ "EH" , 732, "015", URGN_TERRITORY, "002" },
{ "ER" , 232, "014", URGN_TERRITORY, "002" },
{ "ES" , 724, "039", URGN_TERRITORY, "150" },
{ "ET" , 231, "014", URGN_TERRITORY, "002" },
{ "EU" , 967, NULL, URGN_GROUPING, NULL },
{ "FI" , 246, "154", URGN_TERRITORY, "150" },
{ "FJ" , 242, "054", URGN_TERRITORY, "009" },
{ "FK" , 238, "005", URGN_TERRITORY, "019" },
{ "FM" , 583, "057", URGN_TERRITORY, "009" },
{ "FO" , 234, "154", URGN_TERRITORY, "150" },
{ "FR" , 250, "155", URGN_TERRITORY, "150" },
{ "FX" , 250, "155", URGN_TERRITORY, "150" },
{ "GA" , 266, "017", URGN_TERRITORY, "002" },
{ "GB" , 826, "154", URGN_TERRITORY, "150" },
{ "GD" , 308, "029", URGN_TERRITORY, "019" },
{ "GE" , 268, "145", URGN_TERRITORY, "142" },
{ "GF" , 254, "005", URGN_TERRITORY, "019" },
{ "GG" , 831, "154", URGN_TERRITORY, "150" },
{ "GH" , 288, "011", URGN_TERRITORY, "002" },
{ "GI" , 292, "039", URGN_TERRITORY, "150" },
{ "GL" , 304, "021", URGN_TERRITORY, "019" },
{ "GM" , 270, "011", URGN_TERRITORY, "002" },
{ "GN" , 324, "011", URGN_TERRITORY, "002" },
{ "GP" , 312, "029", URGN_TERRITORY, "019" },
{ "GQ" , 226, "017", URGN_TERRITORY, "002" },
{ "GR" , 300, "039", URGN_TERRITORY, "150" },
{ "GS" , 239, "QO" , URGN_TERRITORY, "009" },
{ "GT" , 320, "013", URGN_TERRITORY, "019" },
{ "GU" , 316, "057", URGN_TERRITORY, "009" },
{ "GW" , 624, "011", URGN_TERRITORY, "002" },
{ "GY" , 328, "005", URGN_TERRITORY, "019" },
{ "HK" , 344, "030", URGN_TERRITORY, "142" },
{ "HM" , 334, "QO" , URGN_TERRITORY, "009" },
{ "HN" , 340, "013", URGN_TERRITORY, "019" },
{ "HR" , 191, "039", URGN_TERRITORY, "150" },
{ "HT" , 332, "029", URGN_TERRITORY, "019" },
{ "HU" , 348, "151", URGN_TERRITORY, "150" },
{ "IC" , -1, "015", URGN_TERRITORY, "002" },
{ "ID" , 360, "035", URGN_TERRITORY, "142" },
{ "IE" , 372, "154", URGN_TERRITORY, "150" },
{ "IL" , 376, "145", URGN_TERRITORY, "142" },
{ "IM" , 833, "154", URGN_TERRITORY, "150" },
{ "IN" , 356, "034", URGN_TERRITORY, "142" },
{ "IO" , 86, "QO" , URGN_TERRITORY, "009" },
{ "IQ" , 368, "145", URGN_TERRITORY, "142" },
{ "IR" , 364, "034", URGN_TERRITORY, "142" },
{ "IS" , 352, "154", URGN_TERRITORY, "150" },
{ "IT" , 380, "039", URGN_TERRITORY, "150" },
{ "JE" , 832, "154", URGN_TERRITORY, "150" },
{ "JM" , 388, "029", URGN_TERRITORY, "019" },
{ "JO" , 400, "145", URGN_TERRITORY, "142" },
{ "JP" , 392, "030", URGN_TERRITORY, "142" },
{ "KE" , 404, "014", URGN_TERRITORY, "002" },
{ "KG" , 417, "143", URGN_TERRITORY, "142" },
{ "KH" , 116, "035", URGN_TERRITORY, "142" },
{ "KI" , 296, "057", URGN_TERRITORY, "009" },
{ "KM" , 174, "014", URGN_TERRITORY, "002" },
{ "KN" , 659, "029", URGN_TERRITORY, "019" },
{ "KP" , 408, "030", URGN_TERRITORY, "142" },
{ "KR" , 410, "030", URGN_TERRITORY, "142" },
{ "KW" , 414, "145", URGN_TERRITORY, "142" },
{ "KY" , 136, "029", URGN_TERRITORY, "019" },
{ "KZ" , 398, "143", URGN_TERRITORY, "142" },
{ "LA" , 418, "035", URGN_TERRITORY, "142" },
{ "LB" , 422, "145", URGN_TERRITORY, "142" },
{ "LC" , 662, "029", URGN_TERRITORY, "019" },
{ "LI" , 438, "155", URGN_TERRITORY, "150" },
{ "LK" , 144, "034", URGN_TERRITORY, "142" },
{ "LR" , 430, "011", URGN_TERRITORY, "002" },
{ "LS" , 426, "018", URGN_TERRITORY, "002" },
{ "LT" , 440, "154", URGN_TERRITORY, "150" },
{ "LU" , 442, "155", URGN_TERRITORY, "150" },
{ "LV" , 428, "154", URGN_TERRITORY, "150" },
{ "LY" , 434, "015", URGN_TERRITORY, "002" },
{ "MA" , 504, "015", URGN_TERRITORY, "002" },
{ "MC" , 492, "155", URGN_TERRITORY, "150" },
{ "MD" , 498, "151", URGN_TERRITORY, "150" },
{ "ME" , 499, "039", URGN_TERRITORY, "150" },
{ "MF" , 663, "029", URGN_TERRITORY, "019" },
{ "MG" , 450, "014", URGN_TERRITORY, "002" },
{ "MH" , 584, "057", URGN_TERRITORY, "009" },
{ "MK" , 807, "039", URGN_TERRITORY, "150" },
{ "ML" , 466, "011", URGN_TERRITORY, "002" },
{ "MM" , 104, "035", URGN_TERRITORY, "142" },
{ "MN" , 496, "030", URGN_TERRITORY, "142" },
{ "MO" , 446, "030", URGN_TERRITORY, "142" },
{ "MP" , 580, "057", URGN_TERRITORY, "009" },
{ "MQ" , 474, "029", URGN_TERRITORY, "019" },
{ "MR" , 478, "011", URGN_TERRITORY, "002" },
{ "MS" , 500, "029", URGN_TERRITORY, "019" },
{ "MT" , 470, "039", URGN_TERRITORY, "150" },
{ "MU" , 480, "014", URGN_TERRITORY, "002" },
{ "MV" , 462, "034", URGN_TERRITORY, "142" },
{ "MW" , 454, "014", URGN_TERRITORY, "002" },
{ "MX" , 484, "013", URGN_TERRITORY, "019"},
{ "MY" , 458, "035", URGN_TERRITORY, "142" },
{ "MZ" , 508, "014", URGN_TERRITORY, "002" },
{ "NA" , 516, "018", URGN_TERRITORY, "002" },
{ "NC" , 540, "054", URGN_TERRITORY, "009" },
{ "NE" , 562, "011", URGN_TERRITORY, "002" },
{ "NF" , 574, "053", URGN_TERRITORY, "009" },
{ "NG" , 566, "011", URGN_TERRITORY, "002" },
{ "NI" , 558, "013", URGN_TERRITORY, "019" },
{ "NL" , 528, "155", URGN_TERRITORY, "150" },
{ "NO" , 578, "154", URGN_TERRITORY, "150" },
{ "NP" , 524, "034", URGN_TERRITORY, "142" },
{ "NR" , 520, "057", URGN_TERRITORY, "009" },
{ "NT" , 536, NULL , URGN_DEPRECATED, NULL },
{ "NU" , 570, "061", URGN_TERRITORY, "009" },
{ "NZ" , 554, "053", URGN_TERRITORY, "009" },
{ "OM" , 512, "145", URGN_TERRITORY, "142" },
{ "PA" , 591, "013", URGN_TERRITORY, "019" },
{ "PE" , 604, "005", URGN_TERRITORY, "019" },
{ "PF" , 258, "061", URGN_TERRITORY, "009" },
{ "PG" , 598, "054", URGN_TERRITORY, "009" },
{ "PH" , 608, "035", URGN_TERRITORY, "142" },
{ "PK" , 586, "034", URGN_TERRITORY, "142" },
{ "PL" , 616, "151", URGN_TERRITORY, "150" },
{ "PM" , 666, "021", URGN_TERRITORY, "019" },
{ "PN" , 612, "061", URGN_TERRITORY, "009" },
{ "PR" , 630, "029", URGN_TERRITORY, "019" },
{ "PS" , 275, "145", URGN_TERRITORY, "142" },
{ "PT" , 620, "039", URGN_TERRITORY, "150" },
{ "PW" , 585, "057", URGN_TERRITORY, "009" },
{ "PY" , 600, "005", URGN_TERRITORY, "019" },
{ "QA" , 634, "145", URGN_TERRITORY, "142" },
{ "QO" , 961, "009", URGN_SUBCONTINENT, "009" },
{ "QU" , 967, NULL, URGN_GROUPING, NULL },
{ "RE" , 638, "014", URGN_TERRITORY, "002" },
{ "RO" , 642, "151", URGN_TERRITORY, "150" },
{ "RS" , 688, "039", URGN_TERRITORY, "150" },
{ "RU" , 643, "151", URGN_TERRITORY, "150" },
{ "RW" , 646, "014", URGN_TERRITORY, "002" },
{ "SA" , 682, "145", URGN_TERRITORY, "142" },
{ "SB" , 90, "054", URGN_TERRITORY, "009" },
{ "SC" , 690, "014", URGN_TERRITORY, "002" },
{ "SD" , 729, "015", URGN_TERRITORY, "002" },
{ "SE" , 752, "154", URGN_TERRITORY, "150" },
{ "SG" , 702, "035", URGN_TERRITORY, "142" },
{ "SH" , 654, "011", URGN_TERRITORY, "002" },
{ "SI" , 705, "039", URGN_TERRITORY, "150" },
{ "SJ" , 744, "154", URGN_TERRITORY, "150" },
{ "SK" , 703, "151", URGN_TERRITORY, "150" },
{ "SL" , 694, "011", URGN_TERRITORY, "002" },
{ "SM" , 674, "039", URGN_TERRITORY, "150" },
{ "SN" , 686, "011", URGN_TERRITORY, "002" },
{ "SO" , 706, "014", URGN_TERRITORY, "002" },
{ "SR" , 740, "005", URGN_TERRITORY, "019" },
{ "SS" , 728, "015", URGN_TERRITORY, "002" },
{ "ST" , 678, "017", URGN_TERRITORY, "002" },
{ "SU" , 810, NULL , URGN_DEPRECATED , NULL},
{ "SV" , 222, "013", URGN_TERRITORY, "019" },
{ "SX" , 534, "029", URGN_TERRITORY, "019" },
{ "SY" , 760, "145", URGN_TERRITORY, "142" },
{ "SZ" , 748, "018", URGN_TERRITORY, "002" },
{ "TA" , -1, "QO", URGN_TERRITORY, "009" },
{ "TC" , 796, "029", URGN_TERRITORY, "019" },
{ "TD" , 148, "017", URGN_TERRITORY, "002" },
{ "TF" , 260, "QO" , URGN_TERRITORY, "009" },
{ "TG" , 768, "011", URGN_TERRITORY, "002" },
{ "TH" , 764, "035", URGN_TERRITORY, "142" },
{ "TJ" , 762, "143", URGN_TERRITORY, "142" },
{ "TK" , 772, "061", URGN_TERRITORY, "009" },
{ "TL" , 626, "035", URGN_TERRITORY, "142" },
{ "TM" , 795, "143", URGN_TERRITORY, "142" },
{ "TN" , 788, "015", URGN_TERRITORY, "002" },
{ "TO" , 776, "061", URGN_TERRITORY, "009" },
{ "TP" , 626, "035", URGN_TERRITORY, "142" },
{ "TR" , 792, "145", URGN_TERRITORY, "142" },
{ "TT" , 780, "029", URGN_TERRITORY, "019" },
{ "TV" , 798, "061", URGN_TERRITORY, "009" },
{ "TW" , 158, "030", URGN_TERRITORY, "142" },
{ "TZ" , 834, "014", URGN_TERRITORY, "002" },
{ "UA" , 804, "151", URGN_TERRITORY, "150" },
{ "UG" , 800, "014", URGN_TERRITORY, "002" },
{ "UM" , 581, "QO" , URGN_TERRITORY, "009" },
{ "US" , 840, "021", URGN_TERRITORY, "019" },
{ "UY" , 858, "005", URGN_TERRITORY, "019" },
{ "UZ" , 860, "143", URGN_TERRITORY, "142" },
{ "VA" , 336, "039", URGN_TERRITORY, "150" },
{ "VC" , 670, "029", URGN_TERRITORY, "019" },
{ "VE" , 862, "005", URGN_TERRITORY, "019" },
{ "VG" , 92, "029", URGN_TERRITORY, "019" },
{ "VI" , 850, "029", URGN_TERRITORY, "019" },
{ "VN" , 704, "035", URGN_TERRITORY, "142" },
{ "VU" , 548, "054", URGN_TERRITORY, "009" },
{ "WF" , 876, "061", URGN_TERRITORY, "009" },
{ "WS" , 882, "061", URGN_TERRITORY, "009" },
{ "YD" , 887, "145", URGN_TERRITORY, "142" },
{ "YE" , 887, "145", URGN_TERRITORY, "142" },
{ "YT" , 175, "014", URGN_TERRITORY, "002" },
{ "ZA" , 710, "018", URGN_TERRITORY, "002" },
{ "ZM" , 894, "014", URGN_TERRITORY, "002" },
{ "ZR" , 180, "017", URGN_TERRITORY, "002" },
{ "ZW" , 716, "014", URGN_TERRITORY, "002" },
{ "ZZ" , 999, NULL , URGN_UNKNOWN, NULL }
};
// *****************************************************************************
// class RegionTest
// *****************************************************************************
RegionTest::RegionTest() {
}
RegionTest::~RegionTest() {
}
#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
void
RegionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par )
{
optionv = (par && *par=='v');
switch (index) {
CASE(0, TestKnownRegions)
CASE(1, TestGetInstanceString)
CASE(2, TestGetInstanceInt)
CASE(3, TestGetContainedRegions)
CASE(4, TestGetContainedRegionsWithType)
CASE(5, TestGetContainingRegion)
CASE(6, TestGetContainingRegionWithType)
CASE(7, TestGetPreferredValues)
CASE(8, TestContains);
CASE(9, TestAvailableTerritories)
default: name = ""; break;
}
}
void RegionTest::TestKnownRegions() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if ( r ) {
int32_t n = r->getNumericCode();
int32_t e = rd.numeric;
if ( n != e ) {
errln("Numeric code mismatch for region %s. Expected:%d Got:%d",r->getRegionCode(),e,n);
}
if (r->getType() != rd.type) {
errln("Expected region %s to be of type %d. Got: %d",r->getRegionCode(),rd.type,r->getType());
}
int32_t nc = rd.numeric;
if ( nc > 0 ) {
const Region *ncRegion = Region::getInstance(nc,status);
if ( *ncRegion != *r && nc != 891 ) { // 891 is special case - CS and YU both deprecated codes for region 891
errln("Creating region %s by its numeric code returned a different region. Got: %s instead.",r->getRegionCode(),ncRegion->getRegionCode());
}
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestGetInstanceString() {
typedef struct TestData {
const char *inputID;
const char *expectedID;
URegionType expectedType;
} TestData;
static TestData testData[] = {
// Input ID, Expected ID, Expected Type
{ "DE", "DE", URGN_TERRITORY }, // Normal region
{ "QU", "EU", URGN_GROUPING }, // Alias to a grouping
{ "DD", "DE", URGN_TERRITORY }, // Alias to a deprecated region (East Germany) with single preferred value
{ "276", "DE", URGN_TERRITORY }, // Numeric code for Germany
{ "278", "DE", URGN_TERRITORY }, // Numeric code for East Germany (Deprecated)
{ "SU", "SU", URGN_DEPRECATED }, // Alias to a deprecated region with multiple preferred values
{ "AN", "AN", URGN_DEPRECATED }, // Deprecated region with multiple preferred values
{ "SVK", "SK", URGN_TERRITORY } // 3-letter code - Slovakia
};
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(NULL,status);
if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
errln("Calling Region::getInstance(NULL) should have triggered an U_ILLEGAL_ARGUMENT_ERROR, but didn't.");
}
status = U_ZERO_ERROR;
r = Region::getInstance("BOGUS",status);
if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
errln("Calling Region::getInstance(\"BOGUS\") should have triggered an U_ILLEGAL_ARGUMENT_ERROR, but didn't.");
}
for (int32_t i = 0 ; i < LENGTHOF(testData) ; i++ ) {
TestData data = testData[i];
status = U_ZERO_ERROR;
r = Region::getInstance(data.inputID,status);
const char *id;
URegionType type;
if ( r ) {
id = r->getRegionCode();
type = r->getType();
} else {
id = "NULL";
type = URGN_UNKNOWN;
}
if ( uprv_strcmp(id,data.expectedID)) {
errln("Unexpected region ID for Region::getInstance(\"%s\"); Expected: %s Got: %s",data.inputID,data.expectedID,id);
}
if ( type != data.expectedType) {
errln("Unexpected region type for Region::getInstance(\"%s\"); Expected: %d Got: %d",data.inputID,data.expectedType,type);
}
}
}
void RegionTest::TestGetInstanceInt() {
typedef struct TestData {
int32_t inputID;
const char *expectedID;
URegionType expectedType;
} TestData;
static TestData testData[] = {
// Input ID, Expected ID, Expected Type
{ 276, "DE", URGN_TERRITORY }, // Numeric code for Germany
{ 278, "DE", URGN_TERRITORY }, // Numeric code for East Germany (Deprecated)
{ 419, "419", URGN_GROUPING }, // Latin America
{ 736, "SD", URGN_TERRITORY }, // Sudan (pre-2011) - changed numeric code after South Sudan split off
{ 729, "SD", URGN_TERRITORY }, // Sudan (post-2011) - changed numeric code after South Sudan split off
};
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(-123,status);
if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
errln("Calling Region::getInstance(-123) should have triggered an U_ILLEGAL_ARGUMENT_ERROR, but didn't.");
}
for (int32_t i = 0 ; i < LENGTHOF(testData) ; i++ ) {
TestData data = testData[i];
status = U_ZERO_ERROR;
const Region *r = Region::getInstance(data.inputID,status);
const char *id;
URegionType type;
if ( r ) {
id = r->getRegionCode();
type = r->getType();
} else {
id = "NULL";
type = URGN_UNKNOWN;
}
if ( uprv_strcmp(data.expectedID,id)) {
errln("Unexpected region ID for Region.getInstance(%d)); Expected: %s Got: %s",data.inputID,data.expectedID,id);
}
if ( data.expectedType != type) {
errln("Unexpected region type for Region.getInstance(%d)); Expected: %d Got: %d",data.inputID,data.expectedType,type);
}
}
}
void RegionTest::TestGetContainedRegions() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if (r) {
if (r->getType() == URGN_GROUPING) {
continue;
}
StringEnumeration *containedRegions = r->getContainedRegions();
int32_t count = containedRegions->count(status);
for ( int32_t i = 0 ; i < containedRegions->count(status); i++ ) {
const char *crID = containedRegions->next(NULL,status);
const Region *cr = Region::getInstance(crID,status);
const Region *containingRegion = cr ? cr->getContainingRegion() : NULL;
if ( !containingRegion || *containingRegion != *r ) {
errln("Region: %s contains region %s. Expected containing region of this region to be the original region, but got %s",
r->getRegionCode(),cr->getRegionCode(),containingRegion?containingRegion->getRegionCode():"NULL");
}
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestGetContainedRegionsWithType() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if (r) {
if (r->getType() != URGN_CONTINENT) {
continue;
}
StringEnumeration *containedRegions = r->getContainedRegions(URGN_TERRITORY);
for ( int32_t j = 0 ; j < containedRegions->count(status); j++ ) {
const char *crID = containedRegions->next(NULL,status);
const Region *cr = Region::getInstance(crID,status);
const Region *containingRegion = cr ? cr->getContainingRegion(URGN_CONTINENT) : NULL;
if ( !containingRegion || *containingRegion != *r ) {
errln("Continent: %s contains territory %s. Expected containing continent of this region to be the original region, but got %s",
r->getRegionCode(),cr->getRegionCode(),containingRegion?containingRegion->getRegionCode():"NULL");
}
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestGetContainingRegion() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if (r) {
const Region *c = r->getContainingRegion();
if (rd.parent == NULL) {
if ( c ) {
errln("Containing region for %s should have been NULL. Got: %s",r->getRegionCode(),c->getRegionCode());
}
} else {
const Region *p = Region::getInstance(rd.parent,status);
if ( !c || *p != *c ) {
errln("Expected containing continent of region %s to be %s. Got: %s",
r->getRegionCode(),p?p->getRegionCode():"NULL",c?c->getRegionCode():"NULL" );
}
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestGetContainingRegionWithType() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if (r) {
const Region *c = r->getContainingRegion(URGN_CONTINENT);
if (rd.containingContinent == NULL) {
if ( c != NULL) {
errln("Containing continent for %s should have been NULL. Got: %s",r->getRegionCode(), c->getRegionCode());
}
} else {
const Region *p = Region::getInstance(rd.containingContinent,status);
if ( *p != *c ) {
errln("Expected containing continent of region %s to be %s. Got: %s",
r->getRegionCode(),p?p->getRegionCode():"NULL",c?c->getRegionCode():"NULL" );
}
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestGetPreferredValues() {
static const char *testData[6][17] = {
// Input ID, Expected Preferred Values...
{ "AN", "CW", "SX", "BQ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, // Netherlands Antilles
{ "CS", "RS", "ME", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, // Serbia & Montenegro
{ "FQ", "AQ", "TF", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, // French Southern and Antarctic Territories
{ "NT", "IQ", "SA", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, // Neutral Zone
{ "PC", "FM", "MH", "MP", "PW", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, // Pacific Islands Trust Territory
{ "SU", "RU", "AM", "AZ", "BY", "EE", "GE", "KZ", "KG", "LV", "LT", "MD", "TJ", "TM", "UA", "UZ" , NULL}, // Soviet Union
};
for ( int32_t i = 0 ; i < 6 ; i++ ) {
const char **data = testData[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(data[0],status);
if (r) {
StringEnumeration *preferredValues = r->getPreferredValues();
for ( int i = 1 ; data[i] ; i++ ) {
UBool found = FALSE;
preferredValues->reset(status);
while ( const char *check = preferredValues->next(NULL,status) ) {
if ( !uprv_strcmp(check,data[i]) ) {
found = TRUE;
break;
}
}
if ( !found ) {
errln("Region::getPreferredValues() for region \"%s\" should have contained \"%s\" but it didn't.",r->getRegionCode(),data[i]);
}
}
} else {
errln("Known region %s was not recognized.",data[0]);
}
}
}
void RegionTest::TestContains() {
for (int32_t i = 0 ; i < LENGTHOF(knownRegions) ; i++ ) {
KnownRegion rd = knownRegions[i];
UErrorCode status = U_ZERO_ERROR;
const Region *r = Region::getInstance(rd.code,status);
if (r) {
const Region *c = r->getContainingRegion();
while ( c ) {
if ( !c->contains(*r)) {
errln("Region \"%s\" should have contained \"%s\" but it didn't.",c->getRegionCode(),r->getRegionCode());
}
c = c->getContainingRegion();
}
} else {
errln("Known region %s was not recognized.",rd.code);
}
}
}
void RegionTest::TestAvailableTerritories() {
// Test to make sure that the set of territories contained in World and the set of all available
// territories are one and the same.
UErrorCode status = U_ZERO_ERROR;
StringEnumeration *availableTerritories = Region::getAvailable(URGN_TERRITORY);
const Region *world = Region::getInstance("001",status);
StringEnumeration *containedInWorld = world->getContainedRegions(URGN_TERRITORY);
if ( !availableTerritories || !containedInWorld || *availableTerritories != *containedInWorld ) {
char availableTerritoriesString[1024] = "";
char containedInWorldString[1024] = "";
if ( availableTerritories ) {
for (int32_t i = 0 ; i < availableTerritories->count(status) ; i++ ) {
if ( i > 0 ) {
uprv_strcat(availableTerritoriesString," ");
}
uprv_strcat(availableTerritoriesString,availableTerritories->next(NULL,status));
}
} else {
uprv_strcpy(availableTerritoriesString,"NULL");
}
if ( containedInWorld ) {
for (int32_t i = 0 ; i < containedInWorld->count(status) ; i++ ) {
if ( i > 0 ) {
uprv_strcat(containedInWorldString," ");
}
uprv_strcat(containedInWorldString,containedInWorld->next(NULL,status));
}
} else {
uprv_strcpy(containedInWorldString,"NULL");
}
errln("Available territories and all territories contained in world should be the same set.\nAvailable = %s\nContained in World = %s",
availableTerritoriesString,containedInWorldString);
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View File

@ -0,0 +1,47 @@
/************************************************************************
* COPYRIGHT:
* Copyright (c) 2013, International Business Machines Corporation
* and others. All Rights Reserved.
************************************************************************/
#ifndef _REGIONTEST_
#define _REGIONTEST_
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/region.h"
#include "intltest.h"
/**
* Performs various tests on Region APIs
**/
class RegionTest: public IntlTest {
// IntlTest override
void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par );
public:
RegionTest();
virtual ~RegionTest();
void TestKnownRegions(void);
void TestGetInstanceString(void);
void TestGetInstanceInt(void);
void TestGetContainedRegions(void);
void TestGetContainedRegionsWithType(void);
void TestGetContainingRegion(void);
void TestGetContainingRegionWithType(void);
void TestGetPreferredValues(void);
void TestContains(void);
void TestAvailableTerritories(void);
private:
UBool optionv; // TRUE if @v option is given on command line
};
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif // _REGIONTEST_
//eof