Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/intl/components/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 47 kB image not shown  

SSL LocaleGenerated.cpp   Interaktion und
PortierbarkeitC

 
// Generated by make_intl_data.py. DO NOT EDIT.
// Version: CLDR-46
// URL: https://unicode.org/Public/cldr/46/cldr-common-46.0.zip

#include "mozilla/Assertions.h"
#include "mozilla/Span.h"
#include "mozilla/TextUtils.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <string>
#include <type_traits>

#include "mozilla/intl/Locale.h"

using namespace mozilla::intl::LanguageTagLimits;

template <size_t Length, size_t TagLength, size_t SubtagLength>
static inline bool HasReplacement(
    const char (&subtags)[Length][TagLength],
    const mozilla::intl::LanguageTagSubtag<SubtagLength>& subtag) {
  MOZ_ASSERT(subtag.Length() == TagLength - 1,
             "subtag must have the same length as the list of subtags");

  const char* ptr = subtag.Span().data();
  return std::binary_search(std::begin(subtags), std::end(subtags), ptr,
                            [](const char* a, const char* b) {
                              return memcmp(a, b, TagLength - 1) < 0;
                            });
}

template <size_t Length, size_t TagLength, size_t SubtagLength>
static inline const char* SearchReplacement(
    const char (&subtags)[Length][TagLength], const char* (&aliases)[Length],
    const mozilla::intl::LanguageTagSubtag<SubtagLength>& subtag) {
  MOZ_ASSERT(subtag.Length() == TagLength - 1,
             "subtag must have the same length as the list of subtags");

  const char* ptr = subtag.Span().data();
  auto p = std::lower_bound(std::begin(subtags), std::end(subtags), ptr,
                            [](const char* a, const char* b) {
                              return memcmp(a, b, TagLength - 1) < 0;
                            });
  if (p != std::end(subtags) && memcmp(*p, ptr, TagLength - 1) == 0) {
    return aliases[std::distance(std::begin(subtags), p)];
  }
  return nullptr;
}

#ifdef DEBUG
static bool IsAsciiLowercaseAlphanumeric(char c) {
  return mozilla::IsAsciiLowercaseAlpha(c) || mozilla::IsAsciiDigit(c);
}

static bool IsAsciiLowercaseAlphanumericOrDash(char c) {
  return IsAsciiLowercaseAlphanumeric(c) || c == '-';
}

static bool IsCanonicallyCasedLanguageTag(mozilla::Span<const char> span) {
  return std::all_of(span.begin(), span.end(),
                     mozilla::IsAsciiLowercaseAlpha<char>);
}

static bool IsCanonicallyCasedScriptTag(mozilla::Span<const char> span) {
  return mozilla::IsAsciiUppercaseAlpha(span[0]) &&
         std::all_of(span.begin() + 1, span.end(),
                     mozilla::IsAsciiLowercaseAlpha<char>);
}

static bool IsCanonicallyCasedRegionTag(mozilla::Span<const char> span) {
  return std::all_of(span.begin(), span.end(),
                     mozilla::IsAsciiUppercaseAlpha<char>) ||
         std::all_of(span.begin(), span.end(), mozilla::IsAsciiDigit<char>);
}

static bool IsCanonicallyCasedVariantTag(mozilla::Span<const char> span) {
  return std::all_of(span.begin(), span.end(), IsAsciiLowercaseAlphanumeric);
}

static bool IsCanonicallyCasedUnicodeKey(mozilla::Span<const char> key) {
  return std::all_of(key.begin(), key.end(), IsAsciiLowercaseAlphanumeric);
}

static bool IsCanonicallyCasedUnicodeType(mozilla::Span<const char> type) {
  return std::all_of(type.begin(), type.end(),
                     IsAsciiLowercaseAlphanumericOrDash);
}

static bool IsCanonicallyCasedTransformKey(mozilla::Span<const char> key) {
  return std::all_of(key.begin(), key.end(), IsAsciiLowercaseAlphanumeric);
}

static bool IsCanonicallyCasedTransformType(mozilla::Span<const char> type) {
  return std::all_of(type.begin(), type.end(),
                     IsAsciiLowercaseAlphanumericOrDash);
}
#endif

// Mappings from language subtags to preferred values.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::LanguageMapping(LanguageSubtag& language) {
  MOZ_ASSERT(IsStructurallyValidLanguageTag(language.Span()));
  MOZ_ASSERT(IsCanonicallyCasedLanguageTag(language.Span()));

  if (language.Length() == 2) {
    static const char languages[8][3] = {
      "bh""in""iw""ji""jw""mo""tl""tw",
    };
    static const char* aliases[8] = {
      "bho""id""he""yi""jv""ro""fil""ak",
    };

    if (const char* replacement = SearchReplacement(languages, aliases, language)) {
      language.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }

  if (language.Length() == 3) {
    static const char languages[418][4] = {
      "aam""aar""abk""adp""afr""agp""ais""ajp""ajt""aju",
      "aka""alb""als""amh""ara""arb""arg""arm""asd""asm",
      "aue""ava""ave""aym""ayr""ayx""aze""azj""bak""bam",
      "baq""baz""bcc""bcl""bel""ben""bgm""bhk""bic""bih",
      "bis""bjd""bjq""bkb""blg""bod""bos""bre""btb""bul",
      "bur""bxk""bxr""cat""ccq""ces""cha""che""chi""chu",
      "chv""cjr""cka""cld""cmk""cmn""cor""cos""coy""cqu",
      "cre""cwd""cym""cze""daf""dan""dap""deu""dgo""dhd",
      "dik""diq""dit""div""djl""dkl""drh""drr""dud""duj",
      "dut""dwl""dzo""ekk""ell""elp""emk""eng""epo""esk",
      "est""eus""ewe""fao""fas""fat""fij""fin""fra""fre",
      "fry""fuc""ful""gav""gaz""gbc""gbo""geo""ger""gfx",
      "ggn""ggo""ggr""gio""gla""gle""glg""gli""glv""gno",
      "gom""gre""grn""gti""gug""guj""guv""gya""hat""hau",
      "hdn""hea""heb""her""him""hin""hmo""hrr""hrv""hun",
      "hye""ibi""ibo""ice""ido""iii""ike""iku""ile""ill",
      "ilw""ina""ind""ipk""isl""ita""izi""jar""jav""jeg",
      "jpn""kal""kan""kas""kat""kau""kaz""kdv""kgc""kgd",
      "kgh""kgm""khk""khm""kik""kin""kir""kmr""knc""kng",
      "koj""kom""kon""kor""kpp""kpv""krm""ktr""kua""kur",
      "kvs""kwq""kxe""kxl""kzh""kzj""kzt""lak""lao""lat",
      "lav""lbk""leg""lii""lim""lin""lit""llo""lmm""ltz",
      "lub""lug""lvs""mac""mah""mal""mao""mar""may""meg",
      "mgx""mhr""mkd""mlg""mlt""mnk""mnt""mof""mol""mon",
      "mri""msa""mst""mup""mwd""mwj""mya""myd""myt""nad",
      "nau""nav""nbf""nbl""nbx""ncp""nde""ndo""nep""nld",
      "nln""nlr""nno""nns""nnx""nob""nom""noo""nor""npi",
      "nts""nxu""nya""oci""ojg""oji""ori""orm""ory""oss",
      "oun""pan""pat""pbu""pcr""per""pes""pli""plt""pmc",
      "pmk""pmu""pnb""pol""por""ppa""ppr""prp""pry""pus",
      "puz""que""quz""rmr""rmy""roh""ron""rum""run""rus",
      "sag""san""sap""sca""scc""scr""sgl""sin""skk""slk",
      "slo""slv""smd""sme""smo""sna""snb""snd""som""sot",
      "spa""spy""sqi""src""srd""srp""ssw""sul""sum""sun",
      "swa""swe""swh""szd""tah""tam""tat""tdu""tel""tgg",
      "tgk""tgl""tha""thc""thw""thx""tib""tid""tie""tir",
      "tkk""tlw""tmk""tmp""tne""ton""tpw""tsf""tsn""tso",
      "ttq""tuk""tur""twi""uig""ukr""umu""unp""uok""urd",
      "uzb""uzn""ven""vie""vol""wel""wgw""wit""wiw""wln",
      "wol""xba""xho""xia""xkh""xpe""xrq""xsj""xsl""xss",
      "ybd""ydd""yen""yid""yiy""yma""ymt""yor""yos""yuu",
      "zai""zha""zho""zir""zkb""zsm""zul""zyb",
    };
    static const char* aliases[418] = {
      "aas",  "aa",  "ab",  "dz",  "af""apf""ami""apc""aeb""jrb",
       "ak",  "sq",  "sq",  "am",  "ar",  "ar",  "an",  "hy""snz",  "as",
      "ktz",  "av",  "ae",  "ay",  "ay""nun",  "az",  "az",  "ba",  "bm",
       "eu""nvo""bal""bik",  "be",  "bn""bcg""fbl""bir""bho",
       "bi""drl""bzc""ebk""iba",  "bo",  "bs",  "br""beb",  "bg",
       "my""luy""bua",  "ca""rki",  "cs",  "ch",  "ce",  "zh",  "cu",
       "cv""mom""cmr""syr""xch",  "zh",  "kw",  "co""pij""quh",
       "cr",  "cr",  "cy",  "cs""dnj",  "da""njz",  "de""doi""mwr",
      "din""zza""dif",  "dv""dze""aqd",  "mn""kzk""uth""dwu",
       "nl""dbt",  "dz",  "et",  "el""amq""man",  "en",  "eo",  "ik",
       "et",  "eu",  "ee",  "fo",  "fa",  "ak",  "fj",  "fi",  "fr",  "fr",
       "fy",  "ff",  "ff""dev",  "om""wny""grb",  "ka",  "de""vaj",
      "gvr""esg""gtu""aou",  "gd",  "ga",  "gl""kzk",  "gv""gon",
      "kok",  "el",  "gn""nyc",  "gn",  "gu""duz""gba",  "ht",  "ha",
      "hai""hmn",  "he",  "hz""srx",  "hi",  "ho""jal",  "hr",  "hu",
       "hy""opa",  "ig",  "is",  "io",  "ii",  "iu",  "iu",  "ie""ilm",
      "gal",  "ia",  "id",  "ik",  "is",  "it""eza""jgk",  "jv""oyb",
       "ja",  "kl",  "kn",  "ks",  "ka",  "kr",  "kk""zkd""tdf""ncq",
      "kml""plu",  "mn",  "km",  "ki",  "rw",  "ky",  "ku",  "kr",  "kg",
      "kwv",  "kv",  "kg",  "ko""jkm",  "kv""bmf""dtp",  "kj",  "ku",
      "gdj""yam""tvd""kru""dgl""dtp""dtp""ksp",  "lo",  "la",
       "lv""bnc""enl""raq",  "li",  "ln",  "lt""ngt""rmx",  "lb",
       "lu",  "lg",  "lv",  "mk",  "mh",  "ml",  "mi",  "mr",  "ms""cir",
      "jbk""chm",  "mk",  "mg",  "mt""man""wnn""xnt",  "ro",  "mn",
       "mi",  "ms""mry""raj""dmw""vaj",  "my""aog""mry""xny",
       "na",  "nv""nru",  "nr""ekc""kdz",  "nd",  "ng",  "ne",  "nl",
      "azd""nrk",  "nn""nbr""ngv",  "nb""cbr""dtd",  "no",  "ne",
      "pij""bpp",  "ny",  "oc",  "oj",  "oj",  "or",  "om",  "or",  "os",
      "vaj",  "pa""kxr",  "ps""adx",  "fa",  "fa",  "pi",  "mg""huw",
      "crr""phr""lah",  "pl",  "pt""bfy""lcq",  "gu""prt",  "ps",
      "pub",  "qu",  "qu""emx""rom",  "rm",  "ro",  "ro",  "rn",  "ru",
       "sg",  "sa""aqt""hle",  "sr",  "hr""isk",  "si""oyb",  "sk",
       "sk",  "sl""kmb",  "se",  "sm",  "sn""iba",  "sd",  "so",  "st",
       "es""kln",  "sq",  "sc",  "sc",  "sr",  "ss""sgd""ulw",  "su",
       "sw",  "sv",  "sw""umi",  "ty",  "ta",  "tt""dtp",  "te""bjp",
       "tg""fil",  "th""tpo""ola""oyb",  "bo""itd""ras",  "ti",
      "twm""weo""tdg""tyj""kak",  "to""tpn""taj",  "tn",  "ts",
      "tmh",  "tk",  "tr",  "ak",  "ug",  "uk""del""wro""ema",  "ur",
       "uz",  "uz",  "ve",  "vi",  "vo",  "cy""wgb""nol""nwo",  "wa",
       "wo""cax",  "xh""acn""waw""kpe""dmw""suj""den""zko",
      "rki",  "yi""ynq",  "yi""yrm""lrr""mtm",  "yo""zom""yug",
      "zap",  "za",  "zh""scv""kjh",  "ms",  "zu",  "za",
    };

    if (const char* replacement = SearchReplacement(languages, aliases, language)) {
      language.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }

  return false;
}

// Language subtags with complex mappings.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::ComplexLanguageMapping(const LanguageSubtag& language) {
  MOZ_ASSERT(IsStructurallyValidLanguageTag(language.Span()));
  MOZ_ASSERT(IsCanonicallyCasedLanguageTag(language.Span()));

  if (language.Length() == 2) {
    return language.EqualTo("sh");
  }

  if (language.Length() == 3) {
    static const char languages[6][4] = {
      "cnr""drw""hbs""prs""swc""tnf",
    };

    return HasReplacement(languages, language);
  }

  return false;
}

// Mappings from script subtags to preferred values.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::ScriptMapping(ScriptSubtag& script) {
  MOZ_ASSERT(IsStructurallyValidScriptTag(script.Span()));
  MOZ_ASSERT(IsCanonicallyCasedScriptTag(script.Span()));

  {
    if (script.EqualTo("Qaai")) {
      script.Set(mozilla::MakeStringSpan("Zinh"));
      return true;
    }
    return false;
  }
}

// Mappings from region subtags to preferred values.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::RegionMapping(RegionSubtag& region) {
  MOZ_ASSERT(IsStructurallyValidRegionTag(region.Span()));
  MOZ_ASSERT(IsCanonicallyCasedRegionTag(region.Span()));

  if (region.Length() == 2) {
    static const char regions[23][3] = {
      "BU""CS""CT""DD""DY""FQ""FX""HV""JT""MI",
      "NH""NQ""PU""PZ""QU""RH""TP""UK""VD""WK",
      "YD""YU""ZR",
    };
    static const char* aliases[23] = {
      "MM""RS""KI""DE""BJ""AQ""FR""BF""UM""UM",
      "VU""AQ""UM""PA""EU""ZW""TL""GB""VN""UM",
      "YE""RS""CD",
    };

    if (const char* replacement = SearchReplacement(regions, aliases, region)) {
      region.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }

  {
    static const char regions[300][4] = {
      "004""008""010""012""016""020""024""028""031""032",
      "036""040""044""048""050""051""052""056""060""062",
      "064""068""070""072""074""076""084""086""090""092",
      "096""100""104""108""112""116""120""124""132""136",
      "140""144""148""152""156""158""162""166""170""174",
      "175""178""180""184""188""191""192""196""203""204",
      "208""212""214""218""222""226""230""231""232""233",
      "234""238""239""242""246""248""249""250""254""258",
      "260""262""266""268""270""275""276""278""280""288",
      "292""296""300""304""308""312""316""320""324""328",
      "332""334""336""340""344""348""352""356""360""364",
      "368""372""376""380""384""388""392""398""400""404",
      "408""410""414""417""418""422""426""428""430""434",
      "438""440""442""446""450""454""458""462""466""470",
      "474""478""480""484""492""496""498""499""500""504",
      "508""512""516""520""524""528""531""533""534""535",
      "540""548""554""558""562""566""570""574""578""580",
      "581""583""584""585""586""591""598""600""604""608",
      "612""616""620""624""626""630""634""638""642""643",
      "646""652""654""659""660""662""663""666""670""674",
      "678""682""686""688""690""694""702""703""704""705",
      "706""710""716""720""724""728""729""732""736""740",
      "744""748""752""756""760""762""764""768""772""776",
      "780""784""788""792""795""796""798""800""804""807",
      "818""826""830""831""832""833""834""840""850""854",
      "858""860""862""876""882""886""887""891""894""958",
      "959""960""962""963""964""965""966""967""968""969",
      "970""971""972""973""974""975""976""977""978""979",
      "980""981""982""983""984""985""986""987""988""989",
      "990""991""992""993""994""995""996""997""998""999",
    };
    static const char* aliases[300] = {
       "AF",  "AL",  "AQ",  "DZ",  "AS",  "AD",  "AO",  "AG",  "AZ",  "AR",
       "AU",  "AT",  "BS",  "BH",  "BD",  "AM",  "BB",  "BE",  "BM""034",
       "BT",  "BO",  "BA",  "BW",  "BV",  "BR",  "BZ",  "IO",  "SB",  "VG",
       "BN",  "BG",  "MM",  "BI",  "BY",  "KH",  "CM",  "CA",  "CV",  "KY",
       "CF",  "LK",  "TD",  "CL",  "CN",  "TW",  "CX",  "CC",  "CO",  "KM",
       "YT",  "CG",  "CD",  "CK",  "CR",  "HR",  "CU",  "CY",  "CZ",  "BJ",
       "DK",  "DM",  "DO",  "EC",  "SV",  "GQ",  "ET",  "ET",  "ER",  "EE",
       "FO",  "FK",  "GS",  "FJ",  "FI",  "AX",  "FR",  "FR",  "GF",  "PF",
       "TF",  "DJ",  "GA",  "GE",  "GM",  "PS",  "DE",  "DE",  "DE",  "GH",
       "GI",  "KI",  "GR",  "GL",  "GD",  "GP",  "GU",  "GT",  "GN",  "GY",
       "HT",  "HM",  "VA",  "HN",  "HK",  "HU",  "IS",  "IN",  "ID",  "IR",
       "IQ",  "IE",  "IL",  "IT",  "CI",  "JM",  "JP",  "KZ",  "JO",  "KE",
       "KP",  "KR",  "KW",  "KG",  "LA",  "LB",  "LS",  "LV",  "LR",  "LY",
       "LI",  "LT",  "LU",  "MO",  "MG",  "MW",  "MY",  "MV",  "ML",  "MT",
       "MQ",  "MR",  "MU",  "MX",  "MC",  "MN",  "MD",  "ME",  "MS",  "MA",
       "MZ",  "OM",  "NA",  "NR",  "NP",  "NL",  "CW",  "AW",  "SX",  "BQ",
       "NC",  "VU",  "NZ",  "NI",  "NE",  "NG",  "NU",  "NF",  "NO",  "MP",
       "UM",  "FM",  "MH",  "PW",  "PK",  "PA",  "PG",  "PY",  "PE",  "PH",
       "PN",  "PL",  "PT",  "GW",  "TL",  "PR",  "QA",  "RE",  "RO",  "RU",
       "RW",  "BL",  "SH",  "KN",  "AI",  "LC",  "MF",  "PM",  "VC",  "SM",
       "ST",  "SA",  "SN",  "RS",  "SC",  "SL",  "SG",  "SK",  "VN",  "SI",
       "SO",  "ZA",  "ZW",  "YE",  "ES",  "SS",  "SD",  "EH",  "SD",  "SR",
       "SJ",  "SZ",  "SE",  "CH",  "SY",  "TJ",  "TH",  "TG",  "TK",  "TO",
       "TT",  "AE",  "TN",  "TR",  "TM",  "TC",  "TV",  "UG",  "UA",  "MK",
       "EG",  "GB",  "JE",  "GG",  "JE",  "IM",  "TZ",  "US",  "VI",  "BF",
       "UY",  "UZ",  "VE",  "WF",  "WS",  "YE",  "YE",  "RS",  "ZM",  "AA",
       "QM",  "QN",  "QP",  "QQ",  "QR",  "QS",  "QT",  "EU",  "QV",  "QW",
       "QX",  "QY",  "QZ",  "XA",  "XB",  "XC",  "XD",  "XE",  "XF",  "XG",
       "XH",  "XI",  "XJ",  "XK",  "XL",  "XM",  "XN",  "XO",  "XP",  "XQ",
       "XR",  "XS",  "XT",  "XU",  "XV",  "XW",  "XX",  "XY",  "XZ",  "ZZ",
    };

    if (const char* replacement = SearchReplacement(regions, aliases, region)) {
      region.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }
}

// Region subtags with complex mappings.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::ComplexRegionMapping(const RegionSubtag& region) {
  MOZ_ASSERT(IsStructurallyValidRegionTag(region.Span()));
  MOZ_ASSERT(IsCanonicallyCasedRegionTag(region.Span()));

  if (region.Length() == 2) {
    return region.EqualTo("AN") ||
           region.EqualTo("NT") ||
           region.EqualTo("PC") ||
           region.EqualTo("SU");
  }

  {
    static const char regions[8][4] = {
      "172""200""530""532""536""582""810""890",
    };

    return HasReplacement(regions, region);
  }
}

// Language subtags with complex mappings.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
void mozilla::intl::Locale::PerformComplexLanguageMappings() {
  MOZ_ASSERT(IsStructurallyValidLanguageTag(Language().Span()));
  MOZ_ASSERT(IsCanonicallyCasedLanguageTag(Language().Span()));

  if (Language().EqualTo("cnr")) {
    SetLanguage("sr");
    if (Region().Missing()) {
      SetRegion("ME");
    }
  }
  else if (Language().EqualTo("drw") ||
           Language().EqualTo("prs") ||
           Language().EqualTo("tnf")) {
    SetLanguage("fa");
    if (Region().Missing()) {
      SetRegion("AF");
    }
  }
  else if (Language().EqualTo("hbs") ||
           Language().EqualTo("sh")) {
    SetLanguage("sr");
    if (Script().Missing()) {
      SetScript("Latn");
    }
  }
  else if (Language().EqualTo("swc")) {
    SetLanguage("sw");
    if (Region().Missing()) {
      SetRegion("CD");
    }
  }
}

// Region subtags with complex mappings.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
void mozilla::intl::Locale::PerformComplexRegionMappings() {
  MOZ_ASSERT(IsStructurallyValidLanguageTag(Language().Span()));
  MOZ_ASSERT(IsCanonicallyCasedLanguageTag(Language().Span()));
  MOZ_ASSERT(IsStructurallyValidRegionTag(Region().Span()));
  MOZ_ASSERT(IsCanonicallyCasedRegionTag(Region().Span()));

  if (Region().EqualTo("172")) {
    if (Language().EqualTo("axm") ||
        Language().EqualTo("hy") ||
        Language().EqualTo("hyw") ||
        Language().EqualTo("rmi") ||
        (Language().EqualTo("und") && Script().EqualTo("Armn"))) {
      SetRegion("AM");
    }
    else if (Language().EqualTo("az") ||
             Language().EqualTo("bdk") ||
             Language().EqualTo("kjj") ||
             Language().EqualTo("kry") ||
             Language().EqualTo("tkr") ||
             Language().EqualTo("tly") ||
             Language().EqualTo("ttt") ||
             (Language().EqualTo("und") && Script().EqualTo("Aghb")) ||
             Language().EqualTo("xag")) {
      SetRegion("AZ");
    }
    else if (Language().EqualTo("be")) {
      SetRegion("BY");
    }
    else if (Language().EqualTo("ab") ||
             Language().EqualTo("bbl") ||
             Language().EqualTo("bhn") ||
             Language().EqualTo("jge") ||
             Language().EqualTo("ka") ||
             (Language().EqualTo("ku") && Script().EqualTo("Yezi")) ||
             Language().EqualTo("oav") ||
             Language().EqualTo("os") ||
             Language().EqualTo("sva") ||
             (Language().EqualTo("und") && Script().EqualTo("Geor")) ||
             (Language().EqualTo("und") && Script().EqualTo("Yezi")) ||
             Language().EqualTo("uum") ||
             Language().EqualTo("xmf")) {
      SetRegion("GE");
    }
    else if (Language().EqualTo("dng") ||
             Language().EqualTo("ky")) {
      SetRegion("KG");
    }
    else if (Language().EqualTo("kk") ||
             (Language().EqualTo("ug") && Script().EqualTo("Cyrl"))) {
      SetRegion("KZ");
    }
    else if (Language().EqualTo("gag")) {
      SetRegion("MD");
    }
    else if (Language().EqualTo("abh") ||
             Language().EqualTo("paq") ||
             Language().EqualTo("sgh") ||
             Language().EqualTo("tg") ||
             Language().EqualTo("yah") ||
             Language().EqualTo("yai")) {
      SetRegion("TJ");
    }
    else if (Language().EqualTo("chg") ||
             Language().EqualTo("tk")) {
      SetRegion("TM");
    }
    else if (Language().EqualTo("crh") ||
             Language().EqualTo("got") ||
             Language().EqualTo("jct") ||
             Language().EqualTo("ji") ||
             Language().EqualTo("rue") ||
             Language().EqualTo("uk") ||
             (Language().EqualTo("und") && Script().EqualTo("Goth")) ||
             Language().EqualTo("yi")) {
      SetRegion("UA");
    }
    else if (Language().EqualTo("auz") ||
             Language().EqualTo("kaa") ||
             Language().EqualTo("sog") ||
             (Language().EqualTo("und") && Script().EqualTo("Chrs")) ||
             (Language().EqualTo("und") && Script().EqualTo("Sogd")) ||
             (Language().EqualTo("und") && Script().EqualTo("Sogo")) ||
             Language().EqualTo("uz") ||
             Language().EqualTo("xco")) {
      SetRegion("UZ");
    }
    else {
      SetRegion("RU");
    }
  }
  else if (Region().EqualTo("200")) {
    if (Language().EqualTo("rmc") ||
        Language().EqualTo("sk")) {
      SetRegion("SK");
    }
    else {
      SetRegion("CZ");
    }
  }
  else if (Region().EqualTo("530") ||
           Region().EqualTo("532") ||
           Region().EqualTo("AN")) {
    if (Language().EqualTo("vic")) {
      SetRegion("SX");
    }
    else {
      SetRegion("CW");
    }
  }
  else if (Region().EqualTo("536") ||
           Region().EqualTo("NT")) {
    if (Language().EqualTo("acm") ||
        Language().EqualTo("aii") ||
        Language().EqualTo("akk") ||
        (Language().EqualTo("arc") && Script().EqualTo("Hatr")) ||
        Language().EqualTo("ayp") ||
        Language().EqualTo("bjm") ||
        Language().EqualTo("ckb") ||
        Language().EqualTo("kqd") ||
        (Language().EqualTo("ku") && Script().EqualTo("Arab")) ||
        Language().EqualTo("mid") ||
        Language().EqualTo("sdb") ||
        Language().EqualTo("sdf") ||
        Language().EqualTo("syr") ||
        (Language().EqualTo("und") && Script().EqualTo("Hatr")) ||
        (Language().EqualTo("und") && Script().EqualTo("Syrc")) ||
        (Language().EqualTo("und") && Script().EqualTo("Xsux"))) {
      SetRegion("IQ");
    }
    else {
      SetRegion("SA");
    }
  }
  else if (Region().EqualTo("582") ||
           Region().EqualTo("PC")) {
    if (Language().EqualTo("mh")) {
      SetRegion("MH");
    }
    else if (Language().EqualTo("cal") ||
             Language().EqualTo("tpv")) {
      SetRegion("MP");
    }
    else if (Language().EqualTo("pau") ||
             Language().EqualTo("sov") ||
             Language().EqualTo("tox")) {
      SetRegion("PW");
    }
    else {
      SetRegion("FM");
    }
  }
  else if (Region().EqualTo("810") ||
           Region().EqualTo("SU")) {
    if (Language().EqualTo("axm") ||
        Language().EqualTo("hy") ||
        Language().EqualTo("hyw") ||
        Language().EqualTo("rmi") ||
        (Language().EqualTo("und") && Script().EqualTo("Armn"))) {
      SetRegion("AM");
    }
    else if (Language().EqualTo("az") ||
             Language().EqualTo("bdk") ||
             Language().EqualTo("kjj") ||
             Language().EqualTo("kry") ||
             Language().EqualTo("tkr") ||
             Language().EqualTo("tly") ||
             Language().EqualTo("ttt") ||
             (Language().EqualTo("und") && Script().EqualTo("Aghb")) ||
             Language().EqualTo("xag")) {
      SetRegion("AZ");
    }
    else if (Language().EqualTo("be")) {
      SetRegion("BY");
    }
    else if (Language().EqualTo("et") ||
             Language().EqualTo("ie") ||
             Language().EqualTo("vro")) {
      SetRegion("EE");
    }
    else if (Language().EqualTo("ab") ||
             Language().EqualTo("bbl") ||
             Language().EqualTo("bhn") ||
             Language().EqualTo("jge") ||
             Language().EqualTo("ka") ||
             (Language().EqualTo("ku") && Script().EqualTo("Yezi")) ||
             Language().EqualTo("oav") ||
             Language().EqualTo("os") ||
             Language().EqualTo("sva") ||
             (Language().EqualTo("und") && Script().EqualTo("Geor")) ||
             (Language().EqualTo("und") && Script().EqualTo("Yezi")) ||
             Language().EqualTo("uum") ||
             Language().EqualTo("xmf")) {
      SetRegion("GE");
    }
    else if (Language().EqualTo("dng") ||
             Language().EqualTo("ky")) {
      SetRegion("KG");
    }
    else if (Language().EqualTo("kk") ||
             (Language().EqualTo("ug") && Script().EqualTo("Cyrl"))) {
      SetRegion("KZ");
    }
    else if (Language().EqualTo("kdr") ||
             Language().EqualTo("lt") ||
             Language().EqualTo("olt") ||
             Language().EqualTo("sgs")) {
      SetRegion("LT");
    }
    else if (Language().EqualTo("liv") ||
             Language().EqualTo("ltg") ||
             Language().EqualTo("lv")) {
      SetRegion("LV");
    }
    else if (Language().EqualTo("gag")) {
      SetRegion("MD");
    }
    else if (Language().EqualTo("abh") ||
             Language().EqualTo("paq") ||
             Language().EqualTo("sgh") ||
             Language().EqualTo("tg") ||
             Language().EqualTo("yah") ||
             Language().EqualTo("yai")) {
      SetRegion("TJ");
    }
    else if (Language().EqualTo("chg") ||
             Language().EqualTo("tk")) {
      SetRegion("TM");
    }
    else if (Language().EqualTo("crh") ||
             Language().EqualTo("got") ||
             Language().EqualTo("jct") ||
             Language().EqualTo("ji") ||
             Language().EqualTo("rue") ||
             Language().EqualTo("uk") ||
             (Language().EqualTo("und") && Script().EqualTo("Goth")) ||
             Language().EqualTo("yi")) {
      SetRegion("UA");
    }
    else if (Language().EqualTo("auz") ||
             Language().EqualTo("kaa") ||
             Language().EqualTo("sog") ||
             (Language().EqualTo("und") && Script().EqualTo("Chrs")) ||
             (Language().EqualTo("und") && Script().EqualTo("Sogd")) ||
             (Language().EqualTo("und") && Script().EqualTo("Sogo")) ||
             Language().EqualTo("uz") ||
             Language().EqualTo("xco")) {
      SetRegion("UZ");
    }
    else {
      SetRegion("RU");
    }
  }
  else if (Region().EqualTo("890")) {
    if (Language().EqualTo("bs")) {
      SetRegion("BA");
    }
    else if (Language().EqualTo("ckm") ||
             Language().EqualTo("dlm") ||
             Language().EqualTo("hr") ||
             Language().EqualTo("ist") ||
             Language().EqualTo("ruo")) {
      SetRegion("HR");
    }
    else if (Language().EqualTo("mk")) {
      SetRegion("MK");
    }
    else if (Language().EqualTo("sl")) {
      SetRegion("SI");
    }
    else {
      SetRegion("RS");
    }
  }
}

static const char* ToCharPointer(const char* str) {
  return str;
}

static const char* ToCharPointer(const mozilla::intl::UniqueChars& str) {
  return str.get();
}

template <typename T, typename U = T>
static bool IsLessThan(const T& a, const U& b) {
  return strcmp(ToCharPointer(a), ToCharPointer(b)) < 0;
}

// Mappings from variant subtags to preferred values.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::PerformVariantMappings() {
  // The variant subtags need to be sorted for binary search.
  MOZ_ASSERT(std::is_sorted(mVariants.begin(), mVariants.end(),
                            IsLessThan<decltype(mVariants)::ElementType>));

  auto removeVariantAt = [&](size_t index) {
    mVariants.erase(mVariants.begin() + index);
  };

  auto insertVariantSortedIfNotPresent = [&](const char* variant) {
    auto* p = std::lower_bound(
        mVariants.begin(), mVariants.end(), variant,
        IsLessThan<decltype(mVariants)::ElementType, decltype(variant)>);

    // Don't insert the replacement when already present.
    if (p != mVariants.end() && strcmp(p->get(), variant) == 0) {
      return true;
    }

    // Insert the preferred variant in sort order.
    auto preferred = DuplicateStringToUniqueChars(variant);
    return !!mVariants.insert(p, std::move(preferred));
  };

  for (size_t i = 0; i < mVariants.length();) {
    const char* variant = mVariants[i].get();
    MOZ_ASSERT(IsCanonicallyCasedVariantTag(mozilla::MakeStringSpan(variant)));

    if (strcmp(variant, "arevela") == 0 ||
        strcmp(variant, "arevmda") == 0 ||
        strcmp(variant, "bokmal") == 0 ||
        strcmp(variant, "hakka") == 0 ||
        strcmp(variant, "lojban") == 0 ||
        strcmp(variant, "nynorsk") == 0 ||
        strcmp(variant, "saaho") == 0 ||
        strcmp(variant, "xiang") == 0) {
      removeVariantAt(i);
    }
    else if (strcmp(variant, "aaland") == 0) {
      removeVariantAt(i);
      SetRegion("AX");
    }
    else if (strcmp(variant, "heploc") == 0) {
      removeVariantAt(i);
      if (!insertVariantSortedIfNotPresent("alalc97")) {
        return false;
      }
    }
    else if (strcmp(variant, "polytoni") == 0) {
      removeVariantAt(i);
      if (!insertVariantSortedIfNotPresent("polyton")) {
        return false;
      }
    }
    else {
      i++;
    }
  }
  return true;
}

// Canonicalize legacy locale identifiers.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::UpdateLegacyMappings() {
  // We're mapping legacy tags to non-legacy form here.
  // Other tags remain unchanged.
  //
  // Legacy tags are either sign language tags ("sgn") or have one or multiple
  // variant subtags. Therefore we can quickly exclude most tags by checking
  // these two subtags.

  MOZ_ASSERT(IsCanonicallyCasedLanguageTag(Language().Span()));

  if (!Language().EqualTo("sgn") && mVariants.length() == 0) {
    return true;
  }

#ifdef DEBUG
  for (const auto& variant : Variants()) {
    MOZ_ASSERT(IsStructurallyValidVariantTag(variant));
    MOZ_ASSERT(IsCanonicallyCasedVariantTag(variant));
  }
#endif

  // The variant subtags need to be sorted for binary search.
  MOZ_ASSERT(std::is_sorted(mVariants.begin(), mVariants.end(),
                            IsLessThan<decltype(mVariants)::ElementType>));

  auto findVariant = [this](const char* variant) {
    auto* p = std::lower_bound(mVariants.begin(), mVariants.end(), variant,
                               IsLessThan<decltype(mVariants)::ElementType,
                                          decltype(variant)>);

    if (p != mVariants.end() && strcmp(p->get(), variant) == 0) {
      return p;
    }
    return static_cast<decltype(p)>(nullptr);
  };

  auto insertVariantSortedIfNotPresent = [&](const char* variant) {
    auto* p = std::lower_bound(mVariants.begin(), mVariants.end(), variant,
                               IsLessThan<decltype(mVariants)::ElementType,
                                          decltype(variant)>);

    // Don't insert the replacement when already present.
    if (p != mVariants.end() && strcmp(p->get(), variant) == 0) {
      return true;
    }

    // Insert the preferred variant in sort order.
    auto preferred = DuplicateStringToUniqueChars(variant);
    return !!mVariants.insert(p, std::move(preferred));
  };

  auto removeVariant = [&](auto* p) {
    size_t index = std::distance(mVariants.begin(), p);
    mVariants.erase(mVariants.begin() + index);
  };

  auto removeVariants = [&](auto* p, auto* q) {
    size_t pIndex = std::distance(mVariants.begin(), p);
    size_t qIndex = std::distance(mVariants.begin(), q);
    MOZ_ASSERT(pIndex < qIndex, "variant subtags are sorted");

    mVariants.erase(mVariants.begin() + qIndex);
    mVariants.erase(mVariants.begin() + pIndex);
  };

  if (mVariants.length() >= 2) {
    if (auto* hepburn = findVariant("hepburn")) {
      if (auto* heploc = findVariant("heploc")) {
        removeVariants(hepburn, heploc);

        if (!insertVariantSortedIfNotPresent("alalc97")) {
          return false;
        }
      }
    }
  }

  if (Language().EqualTo("sgn")) {
    if (Region().Present() && SignLanguageMapping(mLanguage, Region())) {
      mRegion.Set(mozilla::MakeStringSpan(""));
    }
  }
  else if (Language().EqualTo("aa") ||
           Language().EqualTo("aar")) {
    if (auto* saaho = findVariant("saaho")) {
      removeVariant(saaho);
      SetLanguage("ssy");
    }
  }
  else if (Language().EqualTo("arm") ||
           Language().EqualTo("hy") ||
           Language().EqualTo("hye")) {
    if (auto* arevmda = findVariant("arevmda")) {
      removeVariant(arevmda);
      SetLanguage("hyw");
    }
  }
  else if (Language().EqualTo("art")) {
    if (auto* lojban = findVariant("lojban")) {
      removeVariant(lojban);
      SetLanguage("jbo");
    }
  }
  else if (Language().EqualTo("cel")) {
    if (auto* gaulish = findVariant("gaulish")) {
      removeVariant(gaulish);
      SetLanguage("xtg");
    }
  }
  else if (Language().EqualTo("chi") ||
           Language().EqualTo("cmn") ||
           Language().EqualTo("zh") ||
           Language().EqualTo("zho")) {
    if (auto* guoyu = findVariant("guoyu")) {
      if (auto* hakka = findVariant("hakka")) {
        removeVariants(guoyu, hakka);
        SetLanguage("hak");
        return true;
      }
    }
    if (auto* guoyu = findVariant("guoyu")) {
      if (auto* xiang = findVariant("xiang")) {
        removeVariants(guoyu, xiang);
        SetLanguage("hsn");
        return true;
      }
    }
    if (auto* guoyu = findVariant("guoyu")) {
      removeVariant(guoyu);
      SetLanguage("zh");
    }
    else if (auto* hakka = findVariant("hakka")) {
      removeVariant(hakka);
      SetLanguage("hak");
    }
    else if (auto* xiang = findVariant("xiang")) {
      removeVariant(xiang);
      SetLanguage("hsn");
    }
  }
  else if (Language().EqualTo("no") ||
           Language().EqualTo("nor")) {
    if (auto* bokmal = findVariant("bokmal")) {
      removeVariant(bokmal);
      SetLanguage("nb");
    }
    else if (auto* nynorsk = findVariant("nynorsk")) {
      removeVariant(nynorsk);
      SetLanguage("nn");
    }
  }

  return true;
}

// Mappings from legacy sign languages.
// Derived from CLDR Supplemental Data, version 46.
// https://unicode.org/Public/cldr/46/cldr-common-46.0.zip
bool mozilla::intl::Locale::SignLanguageMapping(LanguageSubtag& language,
                                                const RegionSubtag& region) {
  MOZ_ASSERT(language.EqualTo("sgn"));
  MOZ_ASSERT(IsStructurallyValidRegionTag(region.Span()));
  MOZ_ASSERT(IsCanonicallyCasedRegionTag(region.Span()));

  if (region.Length() == 2) {
    static const char regions[22][3] = {
      "BR""CO""DD""DE""DK""ES""FR""FX""GB""GR",
      "IE""IT""JP""MX""NI""NL""NO""PT""SE""UK",
      "US""ZA",
    };
    static const char* aliases[22] = {
      "bzs""csn""gsg""gsg""dsl""ssp""fsl""fsl""bfi""gss",
      "isg""ise""jsl""mfs""ncs""dse""nsi""psr""swl""bfi",
      "ase""sfs",
    };

    if (const char* replacement = SearchReplacement(regions, aliases, region)) {
      language.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }

  {
    static const char regions[22][4] = {
      "076""170""208""249""250""276""278""280""300""372",
      "380""392""484""528""558""578""620""710""724""752",
      "826""840",
    };
    static const char* aliases[22] = {
      "bzs""csn""dsl""fsl""fsl""gsg""gsg""gsg""gss""isg",
      "ise""jsl""mfs""dse""ncs""nsi""psr""sfs""ssp""swl",
      "bfi""ase",
    };

    if (const char* replacement = SearchReplacement(regions, aliases, region)) {
      language.Set(mozilla::MakeStringSpan(replacement));
      return true;
    }
    return false;
  }
}

template <size_t Length>
static inline bool IsUnicodeKey(mozilla::Span<const char> key, const char (&str)[Length]) {
  static_assert(Length == UnicodeKeyLength + 1,
                "Unicode extension key is two characters long");
  return memcmp(key.data(), str, Length - 1) == 0;
}

template <size_t Length>
static inline bool IsUnicodeType(mozilla::Span<const char> type, const char (&str)[Length]) {
  static_assert(Length > UnicodeKeyLength + 1,
                "Unicode extension type contains more than two characters");
  return type.size() == (Length - 1) &&
         memcmp(type.data(), str, Length - 1) == 0;
}

static int32_t CompareUnicodeType(const char* a, mozilla::Span<const char> b) {
  MOZ_ASSERT(!std::char_traits<char>::find(b.data(), b.size(), '\0'),
             "unexpected null-character in string");

  using UnsignedChar = unsigned char;
  for (size_t i = 0; i < b.size(); i++) {
    // |a| is zero-terminated and |b| doesn't contain a null-terminator. So if
    // we've reached the end of |a|, the below if-statement will always be true.
    // That ensures we don't read past the end of |a|.
    if (int32_t r = UnsignedChar(a[i]) - UnsignedChar(b[i])) {
      return r;
    }
  }

  // Return zero if both strings are equal or a positive number if |b| is a
  // prefix of |a|.
  return int32_t(UnsignedChar(a[b.size()]));
}

template <size_t Length>
static inline const char* SearchUnicodeReplacement(
  const char* (&types)[Length], const char* (&aliases)[Length],
  mozilla::Span<const char> type) {

  auto p = std::lower_bound(std::begin(types), std::end(types), type,
                            [](const auto& a, const auto& b) {
                              return CompareUnicodeType(a, b) < 0;
                            });
  if (p != std::end(types) && CompareUnicodeType(*p, type) == 0) {
    return aliases[std::distance(std::begin(types), p)];
  }
  return nullptr;
}

/**
 * Mapping from deprecated BCP 47 Unicode extension types to their preferred
 * values.
 *
 * Spec: https://www.unicode.org/reports/tr35/#Unicode_Locale_Extension_Data_Files
 * Spec: https://www.unicode.org/reports/tr35/#t_Extension
 */

const char* mozilla::intl::Locale::ReplaceUnicodeExtensionType(
    mozilla::Span<const char> key, mozilla::Span<const char> type) {
  MOZ_ASSERT(key.size() == UnicodeKeyLength);
  MOZ_ASSERT(IsCanonicallyCasedUnicodeKey(key));

  MOZ_ASSERT(type.size() > UnicodeKeyLength);
  MOZ_ASSERT(IsCanonicallyCasedUnicodeType(type));

  if (IsUnicodeKey(key, "ca")) {
    if (IsUnicodeType(type, "ethiopic-amete-alem")) {
      return "ethioaa";
    }
    if (IsUnicodeType(type, "islamicc")) {
      return "islamic-civil";
    }
  }
  else if (IsUnicodeKey(key, "kb") ||
           IsUnicodeKey(key, "kc") ||
           IsUnicodeKey(key, "kh") ||
           IsUnicodeKey(key, "kk") ||
           IsUnicodeKey(key, "kn")) {
    if (IsUnicodeType(type, "yes")) {
      return "true";
    }
  }
  else if (IsUnicodeKey(key, "ks")) {
    if (IsUnicodeType(type, "primary")) {
      return "level1";
    }
    if (IsUnicodeType(type, "tertiary")) {
      return "level3";
    }
  }
  else if (IsUnicodeKey(key, "ms")) {
    if (IsUnicodeType(type, "imperial")) {
      return "uksystem";
    }
  }
  else if (IsUnicodeKey(key, "rg") ||
           IsUnicodeKey(key, "sd")) {
    static const char* types[147] = {
         "cn11" ,  "cn12" ,  "cn13" ,  "cn14" ,  "cn15" ,  "cn21" ,  "cn22" ,
         "cn23" ,  "cn31" ,  "cn32" ,  "cn33" ,  "cn34" ,  "cn35" ,  "cn36" ,
         "cn37" ,  "cn41" ,  "cn42" ,  "cn43" ,  "cn44" ,  "cn45" ,  "cn46" ,
         "cn50" ,  "cn51" ,  "cn52" ,  "cn53" ,  "cn54" ,  "cn61" ,  "cn62" ,
         "cn63" ,  "cn64" ,  "cn65" ,  "cn71" ,  "cn91" ,  "cn92" , "cz10a" ,
        "cz10b" , "cz10c" , "cz10d" , "cz10e" , "cz10f" , "cz611" , "cz612" ,
        "cz613" , "cz614" , "cz615" , "cz621" , "cz622" , "cz623" , "cz624" ,
        "cz626" , "cz627" ,  "czjc" ,  "czjm" ,  "czka" ,  "czkr" ,  "czli" ,
         "czmo" ,  "czol" ,  "czpa" ,  "czpl" ,  "czpr" ,  "czst" ,  "czus" ,
         "czvy" ,  "czzl" ,  "fi01" ,  "fra"  ,  "frb"  ,  "frbl" ,  "frc"  ,
         "frcp" ,  "frd"  ,  "fre"  ,  "frf"  ,  "frg"  ,  "frgf" ,  "frgp" ,
        "frgua" ,  "frh"  ,  "fri"  ,  "frj"  ,  "frk"  ,  "frl"  , "frlre" ,
         "frm"  , "frmay" ,  "frmf" ,  "frmq" ,  "frn"  ,  "frnc" ,  "fro"  ,
         "frp"  ,  "frpf" ,  "frpm" ,  "frq"  ,  "frr"  ,  "frre" ,  "frs"  ,
         "frt"  ,  "frtf" ,  "fru"  ,  "frv"  ,  "frwf" ,  "fryt" ,  "laxn" ,
         "lud"  ,  "lug"  ,  "lul"  , "mrnkc" ,  "nlaw" ,  "nlcw" ,  "nlsx" ,
         "no23" ,  "nzn"  ,  "nzs"  ,  "omba" ,  "omsh" ,  "plds" ,  "plkp" ,
         "pllb" ,  "plld" ,  "pllu" ,  "plma" ,  "plmz" ,  "plop" ,  "plpd" ,
         "plpk" ,  "plpm" ,  "plsk" ,  "plsl" ,  "plwn" ,  "plwp" ,  "plzp" ,
         "shta" , "tteto" , "ttrcm" , "ttwto" , "twkhq" , "twtnq" , "twtpq" ,
        "twtxq" ,  "usas" ,  "usgu" ,  "usmp" ,  "uspr" ,  "usum" ,  "usvi" ,
    };
    static const char* aliases[147] = {
         "cnbj" ,  "cntj" ,  "cnhe" ,  "cnsx" ,  "cnmn" ,  "cnln" ,  "cnjl" ,
         "cnhl" ,  "cnsh" ,  "cnjs" ,  "cnzj" ,  "cnah" ,  "cnfj" ,  "cnjx" ,
         "cnsd" ,  "cnha" ,  "cnhb" ,  "cnhn" ,  "cngd" ,  "cngx" ,  "cnhi" ,
         "cncq" ,  "cnsc" ,  "cngz" ,  "cnyn" ,  "cnxz" ,  "cnsn" ,  "cngs" ,
         "cnqh" ,  "cnnx" ,  "cnxj" , "twzzzz""hkzzzz""mozzzz""cz110" ,
        "cz111" , "cz112" , "cz113" , "cz114" , "cz115" , "cz663" , "cz632" ,
        "cz633" , "cz634" , "cz635" , "cz641" , "cz642" , "cz643" , "cz644" ,
        "cz646" , "cz647" ,  "cz31" ,  "cz64" ,  "cz41" ,  "cz52" ,  "cz51" ,
         "cz80" ,  "cz71" ,  "cz53" ,  "cz32" ,  "cz10" ,  "cz20" ,  "cz42" ,
         "cz63" ,  "cz72" , "axzzzz""frges" , "frnaq" , "blzzzz""frara" ,
        "cpzzzz""frbfc" , "frbre" , "frcvl" , "frges" , "gfzzzz""gpzzzz",
        "gpzzzz""frcor" , "frbfc" , "fridf" , "frocc" , "frnaq" , "rezzzz",
        "frges" , "ytzzzz""mfzzzz""mqzzzz""frocc" , "nczzzz""frhdf" ,
        "frnor" , "pfzzzz""pmzzzz""frnor" , "frpdl" , "rezzzz""frhdf" ,
        "frnaq" , "tfzzzz""frpac" , "frara" , "wfzzzz""ytzzzz",  "laxs" ,
         "lucl" ,  "luec" ,  "luca" ,  "mr13" , "awzzzz""cwzzzz""sxzzzz",
         "no50" , "nzauk" , "nzcan" ,  "ombj" ,  "omsj" ,  "pl02" ,  "pl04" ,
         "pl08" ,  "pl10" ,  "pl06" ,  "pl12" ,  "pl14" ,  "pl16" ,  "pl20" ,
         "pl18" ,  "pl22" ,  "pl26" ,  "pl24" ,  "pl28" ,  "pl30" ,  "pl32" ,
        "tazzzz""tttob" , "ttmrc" , "tttob" , "twkhh" , "twtnn" , "twnwt" ,
        "twtxg" , "aszzzz""guzzzz""mpzzzz""przzzz""umzzzz""vizzzz",
    };
    return SearchUnicodeReplacement(types, aliases, type);
  }
  else if (IsUnicodeKey(key, "tz")) {
    static const char* types[50] = {
         "aqams"  ,  "aukns"  ,  "caffs"  ,  "camtr"  ,  "canpg"  ,  "capnt"  ,
         "cathu"  ,  "cayzf"  ,   "cet"   ,  "cnckg"  ,  "cnhrb"  ,  "cnkhg"  ,
        "cst6cdt" ,   "cuba"  ,   "eet"   ,  "egypt"  ,   "eire"  ,   "est"   ,
        "est5edt" , "factory" ,   "gaza"  ,   "gmt0"  , "hongkong",   "hst"   ,
        "iceland" ,   "iran"  ,  "israel" , "jamaica" ,  "japan"  ,  "libya"  ,
          "met"   ,  "mncoq"  ,   "mst"   , "mst7mdt" ,  "mxstis" ,  "navajo" ,
         "poland" , "portugal",   "prc"   , "pst8pdt" ,   "roc"   ,   "rok"   ,
         "turkey" ,  "uaozh"  ,  "uauzh"  ,   "uct"   ,  "umjon"  , "usnavajo",
          "wet"   ,   "zulu"  ,
    };
    static const char* aliases[50] = {
         "nzakl"  ,  "auhba"  ,  "cawnp"  ,  "cator"  ,  "cator"  ,  "caiql"  ,
         "cator"  ,  "caedm"  ,  "bebru"  ,  "cnsha"  ,  "cnsha"  ,  "cnurc"  ,
         "uschi"  ,  "cuhav"  ,  "grath"  ,  "egcai"  ,  "iedub"  ,  "papty"  ,
         "usnyc"  ,   "unk"   , "gazastrp",   "gmt"   ,  "hkhkg"  ,  "ushnl"  ,
         "isrey"  ,  "irthr"  , "jeruslm" ,  "jmkin"  ,  "jptyo"  ,  "lytip"  ,
         "bebru"  ,  "mnuln"  ,  "usphx"  ,  "usden"  ,  "mxtij"  ,  "usden"  ,
         "plwaw"  ,  "ptlis"  ,  "cnsha"  ,  "uslax"  ,  "twtpe"  ,  "krsel"  ,
         "trist"  ,  "uaiev"  ,  "uaiev"  ,   "utc"   ,  "ushnl"  ,  "usden"  ,
         "ptlis"  ,   "utc"   ,
    };
    return SearchUnicodeReplacement(types, aliases, type);
  }
  return nullptr;
}

template <size_t Length>
static inline bool IsTransformKey(mozilla::Span<const char> key, const char (&str)[Length]) {
  static_assert(Length == TransformKeyLength + 1,
                "Transform extension key is two characters long");
  return memcmp(key.data(), str, Length - 1) == 0;
}

template <size_t Length>
static inline bool IsTransformType(mozilla::Span<const char> type, const char (&str)[Length]) {
  static_assert(Length > TransformKeyLength + 1,
                "Transform extension type contains more than two characters");
  return type.size() == (Length - 1) &&
         memcmp(type.data(), str, Length - 1) == 0;
}

/**
 * Mapping from deprecated BCP 47 Transform extension types to their preferred
 * values.
 *
 * Spec: https://www.unicode.org/reports/tr35/#Unicode_Locale_Extension_Data_Files
 * Spec: https://www.unicode.org/reports/tr35/#t_Extension
 */

const char* mozilla::intl::Locale::ReplaceTransformExtensionType(
    mozilla::Span<const char> key, mozilla::Span<const char> type) {
  MOZ_ASSERT(key.size() == TransformKeyLength);
  MOZ_ASSERT(IsCanonicallyCasedTransformKey(key));

  MOZ_ASSERT(type.size() > TransformKeyLength);
  MOZ_ASSERT(IsCanonicallyCasedTransformType(type));

  if (IsTransformKey(key, "d0")) {
    if (IsTransformType(type, "name")) {
      return "charname";
    }
  }
  else if (IsTransformKey(key, "m0")) {
    if (IsTransformType(type, "beta-metsehaf")) {
      return "betamets";
    }
    if (IsTransformType(type, "ies-jes")) {
      return "iesjes";
    }
    if (IsTransformType(type, "names")) {
      return "prprname";
    }
    if (IsTransformType(type, "tekie-alibekit")) {
      return "tekieali";
    }
  }
  return nullptr;
}

Messung V0.5
C=96 H=99 G=97

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.34Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.