summaryrefslogtreecommitdiff
path: root/i18nlangtag/source/languagetag/languagetag.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'i18nlangtag/source/languagetag/languagetag.cxx')
-rw-r--r--i18nlangtag/source/languagetag/languagetag.cxx89
1 files changed, 48 insertions, 41 deletions
diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx
index 07b9c6d0a666..41f23973020f 100644
--- a/i18nlangtag/source/languagetag/languagetag.cxx
+++ b/i18nlangtag/source/languagetag/languagetag.cxx
@@ -49,19 +49,24 @@ struct myLtError
~myLtError() { if (p) lt_error_unref( p); }
};
+// "static" to be returned as const reference to an empty locale.
+struct theEmptyLocale : public rtl::Static< lang::Locale, theEmptyLocale > {};
}
typedef std::unordered_set< OUString > KnownTagSet;
namespace {
+struct theKnowns : public rtl::Static< KnownTagSet, theKnowns > {};
struct theMutex : public rtl::Static< osl::Mutex, theMutex > {};
}
static const KnownTagSet & getKnowns()
{
- static const KnownTagSet theKnowns =
- []()
+ KnownTagSet & rKnowns = theKnowns::get();
+ if (rKnowns.empty())
+ {
+ osl::MutexGuard aGuard( theMutex::get());
+ if (rKnowns.empty())
{
- KnownTagSet knownSet;
::std::vector< MsLangId::LanguagetagMapping > aDefined( MsLangId::getDefinedLanguagetags());
for (auto const& elemDefined : aDefined)
{
@@ -71,12 +76,12 @@ static const KnownTagSet & getKnowns()
::std::vector< OUString > aFallbacks( LanguageTag( elemDefined.mnLang).getFallbackStrings( true));
for (auto const& fallback : aFallbacks)
{
- knownSet.insert(fallback);
+ rKnowns.insert(fallback);
}
}
- return knownSet;
- }();
- return theKnowns;
+ }
+ }
+ return rKnowns;
}
@@ -90,10 +95,10 @@ struct compareIgnoreAsciiCaseLess
};
typedef ::std::map< OUString, LanguageTag::ImplPtr, compareIgnoreAsciiCaseLess > MapBcp47;
typedef ::std::map< LanguageType, LanguageTag::ImplPtr > MapLangID;
-MapBcp47 theMapBcp47;
-MapLangID theMapLangID;
-LanguageTag::ImplPtr theDontKnow;
-LanguageTag::ImplPtr theSystemLocale;
+struct theMapBcp47 : public rtl::Static< MapBcp47, theMapBcp47 > {};
+struct theMapLangID : public rtl::Static< MapLangID, theMapLangID > {};
+struct theDontKnow : public rtl::Static< LanguageTag::ImplPtr, theDontKnow > {};
+struct theSystemLocale : public rtl::Static< LanguageTag::ImplPtr, theSystemLocale > {};
}
@@ -593,9 +598,10 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID
osl::MutexGuard aGuard( theMutex::get());
- MapBcp47::const_iterator it( theMapBcp47.find( maBcp47));
+ MapBcp47& rMapBcp47 = theMapBcp47::get();
+ MapBcp47::const_iterator it( rMapBcp47.find( maBcp47));
bool bOtherImpl = false;
- if (it != theMapBcp47.end())
+ if (it != rMapBcp47.end())
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: found impl for '" << maBcp47 << "'");
pImpl = (*it).second;
@@ -615,7 +621,7 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: new impl for '" << maBcp47 << "'");
pImpl = std::make_shared<LanguageTagImpl>( *this);
- theMapBcp47.insert( ::std::make_pair( maBcp47, pImpl));
+ rMapBcp47.insert( ::std::make_pair( maBcp47, pImpl));
}
if (!bOtherImpl || !pImpl->mbInitializedLangID)
@@ -628,8 +634,9 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID
// different, otherwise we would end up with ambiguous assignments
// of different language tags, for example for the same primary
// LangID with "no", "nb" and "nn".
- MapLangID::const_iterator itID( theMapLangID.find( nRegisterID));
- if (itID != theMapLangID.end())
+ const MapLangID& rMapLangID = theMapLangID::get();
+ MapLangID::const_iterator itID( rMapLangID.find( nRegisterID));
+ if (itID != rMapLangID.end())
{
if ((*itID).second->maBcp47 != maBcp47)
{
@@ -660,7 +667,7 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID
}
::std::pair< MapLangID::const_iterator, bool > res(
- theMapLangID.insert( ::std::make_pair( pImpl->mnLangID, pImpl)));
+ theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl)));
if (res.second)
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: cross-inserted 0x"
@@ -679,8 +686,9 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID
LanguageTag::ScriptType LanguageTag::getOnTheFlyScriptType( LanguageType nRegisterID )
{
- MapLangID::const_iterator itID( theMapLangID.find( nRegisterID));
- if (itID != theMapLangID.end())
+ const MapLangID& rMapLangID = theMapLangID::get();
+ MapLangID::const_iterator itID( rMapLangID.find( nRegisterID));
+ if (itID != rMapLangID.end())
return (*itID).second->getScriptType();
else
return ScriptType::UNKNOWN;
@@ -701,7 +709,7 @@ void LanguageTag::setConfiguredSystemLanguage( LanguageType nLang )
MsLangId::LanguageTagAccess::setConfiguredSystemLanguage( nLang);
// Reset system locale to none and let registerImpl() do the rest to
// initialize a new one.
- theSystemLocale.reset();
+ theSystemLocale::get().reset();
LanguageTag aLanguageTag( LANGUAGE_SYSTEM);
aLanguageTag.registerImpl();
}
@@ -741,7 +749,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
// and take the system locale shortcut if possible.
if (mbSystemLocale)
{
- pImpl = theSystemLocale;
+ pImpl = theSystemLocale::get();
if (pImpl)
{
#if OSL_DEBUG_LEVEL > 0
@@ -766,9 +774,10 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
// Heavy usage of LANGUAGE_DONTKNOW, make it an own Impl for all the
// conversion attempts. At the same time provide a central breakpoint
// to inspect such places.
- if (!theDontKnow)
- theDontKnow = std::make_shared<LanguageTagImpl>( *this);
- pImpl = theDontKnow;
+ LanguageTag::ImplPtr& rDontKnow = theDontKnow::get();
+ if (!rDontKnow)
+ rDontKnow = std::make_shared<LanguageTagImpl>( *this);
+ pImpl = rDontKnow;
#if OSL_DEBUG_LEVEL > 0
static size_t nCallsDontKnow = 0;
++nCallsDontKnow;
@@ -779,7 +788,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
else
{
// A great share are calls for a system equal locale.
- pImpl = theSystemLocale;
+ pImpl = theSystemLocale::get();
if (pImpl && pImpl->mnLangID == mnLangID)
{
#if OSL_DEBUG_LEVEL > 0
@@ -810,7 +819,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
if (mbInitializedBcp47)
{
// A great share are calls for a system equal locale.
- pImpl = theSystemLocale;
+ pImpl = theSystemLocale::get();
if (pImpl && pImpl->maBcp47 == maBcp47)
{
#if OSL_DEBUG_LEVEL > 0
@@ -843,8 +852,9 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
// Prefer LangID map as find+insert needs less comparison work.
if (mbInitializedLangID)
{
- MapLangID::const_iterator it( theMapLangID.find( mnLangID));
- if (it != theMapLangID.end())
+ MapLangID& rMap = theMapLangID::get();
+ MapLangID::const_iterator it( rMap.find( mnLangID));
+ if (it != rMap.end())
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: found impl for 0x" << ::std::hex << mnLangID);
pImpl = (*it).second;
@@ -853,7 +863,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: new impl for 0x" << ::std::hex << mnLangID);
pImpl = std::make_shared<LanguageTagImpl>( *this);
- theMapLangID.insert( ::std::make_pair( mnLangID, pImpl));
+ rMap.insert( ::std::make_pair( mnLangID, pImpl));
// Try round-trip.
if (!pImpl->mbInitializedLocale)
pImpl->convertLangToLocale();
@@ -864,7 +874,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
if (!pImpl->mbInitializedBcp47)
pImpl->convertLocaleToBcp47();
::std::pair< MapBcp47::const_iterator, bool > res(
- theMapBcp47.insert( ::std::make_pair( pImpl->maBcp47, pImpl)));
+ theMapBcp47::get().insert( ::std::make_pair( pImpl->maBcp47, pImpl)));
if (res.second)
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: cross-inserted '" << pImpl->maBcp47 << "' for 0x" << ::std::hex << mnLangID);
@@ -885,8 +895,9 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
}
else if (!maBcp47.isEmpty())
{
- MapBcp47::const_iterator it( theMapBcp47.find( maBcp47));
- if (it != theMapBcp47.end())
+ MapBcp47& rMap = theMapBcp47::get();
+ MapBcp47::const_iterator it( rMap.find( maBcp47));
+ if (it != rMap.end())
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: found impl for '" << maBcp47 << "'");
pImpl = (*it).second;
@@ -895,14 +906,14 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: new impl for '" << maBcp47 << "'");
pImpl = std::make_shared<LanguageTagImpl>( *this);
- ::std::pair< MapBcp47::iterator, bool > insOrig( theMapBcp47.insert( ::std::make_pair( maBcp47, pImpl)));
+ ::std::pair< MapBcp47::iterator, bool > insOrig( rMap.insert( ::std::make_pair( maBcp47, pImpl)));
// If changed after canonicalize() also add the resulting tag to
// the map.
if (pImpl->synCanonicalize())
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: canonicalized to '" << pImpl->maBcp47 << "'");
::std::pair< MapBcp47::const_iterator, bool > insCanon(
- theMapBcp47.insert( ::std::make_pair( pImpl->maBcp47, pImpl)));
+ rMap.insert( ::std::make_pair( pImpl->maBcp47, pImpl)));
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: " << (insCanon.second ? "" : "not ")
<< "inserted '" << pImpl->maBcp47 << "'");
// If the canonicalized tag already existed (was not inserted)
@@ -946,7 +957,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
if (bInsert)
{
::std::pair< MapLangID::const_iterator, bool > res(
- theMapLangID.insert( ::std::make_pair( pImpl->mnLangID, pImpl)));
+ theMapLangID::get().insert( ::std::make_pair( pImpl->mnLangID, pImpl)));
if (res.second)
{
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: cross-inserted 0x"
@@ -978,7 +989,7 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const
// above, so add it.
if (mbSystemLocale && mbInitializedLangID)
{
- theSystemLocale = pImpl;
+ theSystemLocale::get() = pImpl;
SAL_INFO( "i18nlangtag", "LanguageTag::registerImpl: added system locale 0x"
<< ::std::hex << pImpl->mnLangID << " '" << pImpl->maBcp47 << "'");
}
@@ -1688,11 +1699,7 @@ OUString LanguageTagImpl::getVariantsFromLangtag()
const css::lang::Locale & LanguageTag::getLocale( bool bResolveSystem ) const
{
if (!bResolveSystem && mbSystemLocale)
- {
- // "static" to be returned as const reference to an empty locale.
- static const lang::Locale theEmptyLocale;
- return theEmptyLocale;
- }
+ return theEmptyLocale::get();
if (!mbInitializedLocale)
syncVarsFromImpl();
if (!mbInitializedLocale)