Now when all equality operators return standard bool (commit 633438f),
it no longer makes any sense to use the ICU4C constants TRUE & FALSE
or local variables of type UBool for their return value.
The existing polymorphic equality operators that use different types for
the `this` and `other` objects are ambiguous with C++20 resolution rules
that require equality for reversed arguments.
In order to resolve that, while also possibly making the implementation
somewhat simpler overall, the implementation classes (LocaleCacheKey
and DateFmtBestPatternKey) now get normal (non-polymorphic) equality
operators that are trivially non-ambiguous (and as a bonus also don't
need any type casts), while the dynamic type checking logic is moved
into protected helper functions, which in the end are invoked
(without any ambiguity) by friend operators in the base class.
This way, all equality testing of cache key objects ends up taking one
of these two possible paths:
1. Both sides of the equality operator are of the same implementation
type (ie. LocaleCacheKey or DateFmtBestPatternKey):
The type specific equality operator is called directly, comparing the
relevant attributes of the two objects directly.
2. The two sides of the equality operator are either of different types
or of some base class type:
The friend equality operators of CacheKeyBase call the virtual helper
function to figure out whether the two objects are actually of the
same type and if they are and this type is an implementation type
then does the necessary type cast to get to 1.
An operator!=() is already defined by a base class so this class doesn't
need to define it again and not doing so avoids a C++20 ambiguity.
This simplifies the code.
Add test case for LocaleBuilder with default locale with extensions.
Use Locale::getRoot().clone() instead of new Locale();
Add CI build bot with LANG that has extension tags
This is the first step towards improving the error handling and out-of-memory
behavior of UVector::addElement(). A followup PR will add back a new addElement()
with corrected error handling, then additional followups will switch call sites
from the original (renamed) function to the new addElement().
This commit includes no logic or behavior changes; it only renames the existing functions.