Merge branch 'master' into var-subset

This commit is contained in:
Michiharu Ariza 2019-04-17 12:07:15 -07:00
commit c87488b46d
13 changed files with 360 additions and 332 deletions

View File

@ -895,11 +895,18 @@ def language_name_intersection (a, b):
def get_matching_language_name (intersection, candidates): def get_matching_language_name (intersection, candidates):
return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c))))
def same_tag (bcp_47_tag, ot_tags):
return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower ()
for language, tags in sorted (ot.from_bcp_47.items ()): for language, tags in sorted (ot.from_bcp_47.items ()):
if language == '' or '-' in language: if language == '' or '-' in language:
continue continue
commented_out = same_tag (language, tags)
for i, tag in enumerate (tags, start=1): for i, tag in enumerate (tags, start=1):
print (' {\"%s\",\t%s},\t/* ' % (language, hb_tag (tag)), end='') print ('%s{\"%s\",\t%s},' % ('/*' if commented_out else ' ', language, hb_tag (tag)), end='')
if commented_out:
print ('*/', end='')
print ('\t/* ', end='')
bcp_47_name = bcp_47.names.get (language, '') bcp_47_name = bcp_47.names.get (language, '')
bcp_47_name_candidates = bcp_47_name.split ('\n') bcp_47_name_candidates = bcp_47_name.split ('\n')
intersection = language_name_intersection (bcp_47_name, ot.names[tag]) intersection = language_name_intersection (bcp_47_name, ot.names[tag])
@ -1040,7 +1047,8 @@ print (' * @tag: A language tag.')
print (' *') print (' *')
print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to')
print (' * many language tags) and the best tag is not the alphabetically first, or if') print (' * many language tags) and the best tag is not the alphabetically first, or if')
print (' * the best tag consists of multiple subtags.') print (' * the best tag consists of multiple subtags, or if the best tag does not appear')
print (' * in #ot_languages.')
print (' *') print (' *')
print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,')
print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.')
@ -1091,7 +1099,8 @@ def verify_disambiguation_dict ():
'%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag))
elif ot_tag not in disambiguation: elif ot_tag not in disambiguation:
disambiguation[ot_tag] = macrolanguages[0] disambiguation[ot_tag] = macrolanguages[0]
if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]: different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t)))
if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]:
del disambiguation[ot_tag] del disambiguation[ot_tag]
for ot_tag in disambiguation.keys (): for ot_tag in disambiguation.keys ():
expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)

View File

@ -34,30 +34,6 @@
#include "hb-null.hh" #include "hb-null.hh"
struct
{
/* Don't know how to set priority of following. Doesn't work right now. */
//template <typename T>
//uint32_t operator () (const T& v) const
//{ return hb_deref_pointer (v).hash (); }
/* Instead, the following ugly soution: */
template <typename T,
hb_enable_if (!hb_is_integer (hb_remove_const (hb_remove_reference (T))) && !hb_is_pointer (T))>
uint32_t operator () (T&& v) const { return v.hash (); }
template <typename T>
uint32_t operator () (const T *v) const
{ return operator() (*v); }
template <typename T,
hb_enable_if (hb_is_integer (T))>
uint32_t operator () (T v) const
{
/* Knuth's multiplicative method: */
return (uint32_t) v * 2654435761u;
}
} HB_FUNCOBJ (hb_hash);
struct struct
{ {
template <typename T> T template <typename T> T
@ -70,6 +46,25 @@ struct
operator () (const T& v) const { return bool (v); } operator () (const T& v) const { return bool (v); }
} HB_FUNCOBJ (hb_bool); } HB_FUNCOBJ (hb_bool);
struct
{
private:
template <typename T> auto
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref_pointer (v).hash ())
template <typename T,
hb_enable_if (hb_is_integer (T))> auto
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
(
/* Knuth's multiplicative method: */
(uint32_t) v * 2654435761u
)
public:
template <typename T> auto
operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
} HB_FUNCOBJ (hb_hash);
struct struct
{ {
@ -77,26 +72,24 @@ struct
/* Pointer-to-member-function. */ /* Pointer-to-member-function. */
template <typename Appl, typename Val> auto template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a ()) impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
template <typename Appl, typename Val> auto (hb_forward<Val> (hb_deref_pointer (v)).*a ())
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a ())
/* Pointer-to-member. */ /* Pointer-to-member. */
template <typename Appl, typename Val> auto template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a) impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
template <typename Appl, typename Val> auto (hb_forward<Val> (hb_deref_pointer (v)).*a)
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a)
/* Operator(). */ /* Operator(). */
template <typename Appl, typename Val> auto template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward<Val> (v))) impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
template <typename Appl, typename Val> auto (hb_deref_pointer (a) (hb_forward<Val> (v)))
impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward<Val> (v)))
public: public:
template <typename Appl, typename Val> auto template <typename Appl, typename Val> auto
operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR ( operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN
(
impl (hb_forward<Appl> (a), impl (hb_forward<Appl> (a),
hb_forward<Val> (v), hb_forward<Val> (v),
hb_prioritize) hb_prioritize)
@ -108,13 +101,12 @@ struct
private: private:
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v)) impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
(hb_deref_pointer (p).has (v))
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
(
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (
hb_invoke (hb_forward<Pred> (p), hb_invoke (hb_forward<Pred> (p),
hb_forward<Val> (v)) hb_forward<Val> (v))
) )
@ -122,10 +114,10 @@ struct
public: public:
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR ( operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
(bool) impl (hb_forward<Pred> (p), impl (hb_forward<Pred> (p),
hb_forward<Val> (v), hb_forward<Val> (v),
hb_prioritize) hb_prioritize)
) )
} HB_FUNCOBJ (hb_has); } HB_FUNCOBJ (hb_has);
@ -134,13 +126,12 @@ struct
private: private:
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward<Val> (v))) impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
(hb_deref_pointer (f).get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward<Val> (v))) impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
(
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (
hb_invoke (hb_forward<Proj> (f), hb_invoke (hb_forward<Proj> (f),
hb_forward<Val> (v)) hb_forward<Val> (v))
) )
@ -148,7 +139,8 @@ struct
public: public:
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR ( operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
(
impl (hb_forward<Proj> (f), impl (hb_forward<Proj> (f),
hb_forward<Val> (v), hb_forward<Val> (v),
hb_prioritize) hb_prioritize)
@ -176,25 +168,25 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).first) template <typename Pair> auto
operator () (const Pair& pair) const { return pair.first; } operator () (const Pair& pair) const HB_AUTO_RETURN (pair.first)
} HB_FUNCOBJ (hb_first); } HB_FUNCOBJ (hb_first);
struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).second) template <typename Pair> auto
operator () (const Pair& pair) const { return pair.second; } operator () (const Pair& pair) const HB_AUTO_RETURN (pair.second)
} HB_FUNCOBJ (hb_second); } HB_FUNCOBJ (hb_second);
struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> auto
operator () (const T& a, const T2& b) const { return a <= b ? a : b; } operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a <= b ? a : b)
} HB_FUNCOBJ (hb_min); } HB_FUNCOBJ (hb_min);
struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> auto
operator () (const T& a, const T2& b) const { return a >= b ? a : b; } operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a >= b ? a : b)
} HB_FUNCOBJ (hb_max); } HB_FUNCOBJ (hb_max);

View File

@ -47,13 +47,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (), hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
arrayZ (o.arrayZ), length (o.length) {} arrayZ (o.arrayZ), length (o.length) {}
template <typename U = Type, hb_enable_if (hb_is_const (U))> template <typename U = Type, hb_enable_if (hb_is_const (U))>
hb_array_t (const hb_array_t<hb_remove_const (Type)> &o) : arrayZ (o.arrayZ), length (o.length) {} hb_array_t (const hb_array_t<hb_remove_const<Type> > &o) : arrayZ (o.arrayZ), length (o.length) {}
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
template <typename U = Type, hb_enable_if (hb_is_const (U))> template <typename U = Type, hb_enable_if (hb_is_const (U))>
hb_array_t& operator = (const hb_array_t<hb_remove_const (Type)> &o) hb_array_t& operator = (const hb_array_t<hb_remove_const<Type> > &o)
{ arrayZ = o.arrayZ; length = o.length; return *this; } { arrayZ = o.arrayZ; length = o.length; return *this; }
hb_array_t& operator = (const hb_array_t &o) hb_array_t& operator = (const hb_array_t &o)
{ arrayZ = o.arrayZ; length = o.length; return *this; } { arrayZ = o.arrayZ; length = o.length; return *this; }
@ -214,7 +214,7 @@ struct hb_sorted_array_t :
hb_sorted_array_t () : hb_array_t<Type> () {} hb_sorted_array_t () : hb_array_t<Type> () {}
hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {} hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
template <typename U = Type, hb_enable_if (hb_is_const (U))> template <typename U = Type, hb_enable_if (hb_is_const (U))>
hb_sorted_array_t (const hb_sorted_array_t<hb_remove_const (Type)> &o) : hb_array_t<Type> (o) {} hb_sorted_array_t (const hb_sorted_array_t<hb_remove_const<Type> > &o) : hb_array_t<Type> (o) {}
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {} template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}

View File

@ -283,7 +283,7 @@ struct hb_atomic_int_t
template <typename P> template <typename P>
struct hb_atomic_ptr_t struct hb_atomic_ptr_t
{ {
typedef hb_remove_pointer (P) T; typedef hb_remove_pointer<P> T;
void init (T* v_ = nullptr) { set_relaxed (v_); } void init (T* v_ = nullptr) { set_relaxed (v_); }
void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }

View File

@ -81,7 +81,7 @@ struct hb_blob_t
template <typename P> template <typename P>
struct hb_blob_ptr_t struct hb_blob_ptr_t
{ {
typedef hb_remove_pointer (P) T; typedef hb_remove_pointer<P> T;
hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {} hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; } hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }

View File

@ -488,7 +488,7 @@ hb_script_from_string (const char *str, int len)
/** /**
* hb_script_to_iso15924_tag: * hb_script_to_iso15924_tag:
* @script: an #hb_script_ to convert. * @script: an #hb_script_t to convert.
* *
* See hb_script_from_iso15924_tag(). * See hb_script_from_iso15924_tag().
* *
@ -783,7 +783,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv)
static void free_static_C_locale (); static void free_static_C_locale ();
#endif #endif
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (HB_LOCALE_T), static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
hb_C_locale_lazy_loader_t> hb_C_locale_lazy_loader_t>
{ {
static HB_LOCALE_T create () static HB_LOCALE_T create ()

View File

@ -748,7 +748,7 @@ hb_ft_font_create_referenced (FT_Face ft_face)
static void free_static_ft_library (); static void free_static_ft_library ();
#endif #endif
static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (FT_Library), static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
hb_ft_library_lazy_loader_t> hb_ft_library_lazy_loader_t>
{ {
static FT_Library create () static FT_Library create ()

View File

@ -78,7 +78,7 @@ struct hb_iter_t
* it will be returning pointer to temporary rvalue. */ * it will be returning pointer to temporary rvalue. */
template <typename T = item_t, template <typename T = item_t,
hb_enable_if (hb_is_reference (T))> hb_enable_if (hb_is_reference (T))>
hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
item_t operator * () const { return thiz()->__item__ (); } item_t operator * () const { return thiz()->__item__ (); }
item_t operator * () { return thiz()->__item__ (); } item_t operator * () { return thiz()->__item__ (); }
item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
@ -258,8 +258,8 @@ struct hb_is_iterator_of { enum {
template <typename Lhs, typename Rhs, template <typename Lhs, typename Rhs,
hb_enable_if (hb_is_iterator (Lhs))> hb_enable_if (hb_is_iterator (Lhs))>
static inline decltype (hb_declval (Rhs) (hb_declval (Lhs))) static inline auto
operator | (Lhs lhs, const Rhs &rhs) { return rhs (lhs); } operator | (Lhs lhs, const Rhs &rhs) HB_AUTO_RETURN (rhs (lhs))
/* hb_map(), hb_filter(), hb_reduce() */ /* hb_map(), hb_filter(), hb_reduce() */

View File

@ -34,8 +34,37 @@
* C++ template meta-programming & fundamentals used with them. * C++ template meta-programming & fundamentals used with them.
*/ */
/* Void! For when we need a expression-type of void. */
struct hb_void_t { typedef void value; };
/* Void meta-function ala std::void_t
* https://en.cppreference.com/w/cpp/types/void_t */
template<typename... Ts> struct _hb_void_tt { typedef void type; };
template<typename... Ts> using hb_void_tt = typename _hb_void_tt<Ts...>::type;
template<typename Head, typename... Ts> struct _hb_head_tt { typedef Head type; };
template<typename... Ts> using hb_head_tt = typename _hb_head_tt<Ts...>::type;
/* Bool! For when we need to evaluate type-dependent expressions
* in a template argument. */
template <bool b> struct hb_bool_tt { enum { value = b }; };
typedef hb_bool_tt<true> hb_true_t;
typedef hb_bool_tt<false> hb_false_t;
/* Function overloading SFINAE and priority. */
#define HB_RETURN(Ret, E) -> hb_head_tt<Ret, decltype ((E))> { return (E); }
#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
#define HB_VOID_RETURN(E) -> hb_void_tt<decltype ((E))> { (E); }
template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
template <> struct hb_priority<0> {};
#define hb_prioritize hb_priority<16> ()
#define HB_FUNCOBJ(x) static_const x HB_UNUSED #define HB_FUNCOBJ(x) static_const x HB_UNUSED
struct struct
{ {
template <typename T> template <typename T>
@ -56,50 +85,38 @@ template <typename T> static inline T hb_declval ();
template <typename T> struct hb_match_const { typedef T type; enum { value = false }; }; template <typename T> struct hb_match_const { typedef T type; enum { value = false }; };
template <typename T> struct hb_match_const<const T> { typedef T type; enum { value = true }; }; template <typename T> struct hb_match_const<const T> { typedef T type; enum { value = true }; };
#define hb_remove_const(T) typename hb_match_const<T>::type template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
#define hb_is_const(T) hb_match_const<T>::value #define hb_is_const(T) hb_match_const<T>::value
template <typename T> struct hb_match_reference { typedef T type; enum { value = false }; }; template <typename T> struct hb_match_reference { typedef T type; enum { value = false }; };
template <typename T> struct hb_match_reference<T &> { typedef T type; enum { value = true }; }; template <typename T> struct hb_match_reference<T &> { typedef T type; enum { value = true }; };
#define hb_remove_reference(T) typename hb_match_reference<T>::type template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
#define hb_is_reference(T) hb_match_reference<T>::value #define hb_is_reference(T) hb_match_reference<T>::value
template <typename T> struct hb_match_pointer { typedef T type; enum { value = false }; }; template <typename T> struct hb_match_pointer { typedef T type; enum { value = false }; };
template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { value = true }; }; template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { value = true }; };
#define hb_remove_pointer(T) typename hb_match_pointer<T>::type template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
#define hb_is_pointer(T) hb_match_pointer<T>::value #define hb_is_pointer(T) hb_match_pointer<T>::value
struct
{
template <typename T>
T operator () (T v) const { return v; }
template <typename T>
T& operator () (T *v) const { return *v; }
} HB_FUNCOBJ (hb_deref_pointer);
/* std::move and std::forward */ /* std::move and std::forward */
template <typename T> template <typename T>
static hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); } static hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
template <typename T> template <typename T>
static T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; } static T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
template <typename T> template <typename T>
static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
struct
{
template <typename T> auto
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
/* Void! For when we need a expression-type of void. */ template <typename T> auto
struct hb_void_t { typedef void value; }; operator () (T *v) const HB_AUTO_RETURN (*v)
/* Void meta-function ala std::void_t } HB_FUNCOBJ (hb_deref_pointer);
* https://en.cppreference.com/w/cpp/types/void_t */
template<typename... Ts> struct _hb_void_tt { typedef void type; };
template<typename... Ts> using hb_void_tt = typename _hb_void_tt<Ts...>::type;
/* Bool! For when we need to evaluate type-dependent expressions
* in a template argument. */
template <bool b> struct hb_bool_tt { enum { value = b }; };
typedef hb_bool_tt<true> hb_true_t;
typedef hb_bool_tt<false> hb_false_t;
template<bool B, typename T = void> struct hb_enable_if {}; template<bool B, typename T = void> struct hb_enable_if {};
template<typename T> struct hb_enable_if<true, T> { typedef T type; }; template<typename T> struct hb_enable_if<true, T> { typedef T type; };
@ -140,14 +157,5 @@ template <> struct hb_is_integer<signed long long> { enum { value = true }; };
template <> struct hb_is_integer<unsigned long long> { enum { value = true }; }; template <> struct hb_is_integer<unsigned long long> { enum { value = true }; };
#define hb_is_integer(T) hb_is_integer<T>::value #define hb_is_integer(T) hb_is_integer<T>::value
/* Function overloading SFINAE and priority. */
#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); }
#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt<decltype ((E))> { (E); }
template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
template <> struct hb_priority<0> {};
#define hb_prioritize hb_priority<16> ()
#endif /* HB_META_HH */ #endif /* HB_META_HH */

View File

@ -95,7 +95,7 @@ struct Null {
template <typename QType> template <typename QType>
struct NullHelper struct NullHelper
{ {
typedef hb_remove_const (hb_remove_reference (QType)) Type; typedef hb_remove_const<hb_remove_reference<QType> > Type;
static const Type & get_null () { return Null<Type>::get_null (); } static const Type & get_null () { return Null<Type>::get_null (); }
}; };
#define Null(Type) NullHelper<Type>::get_null () #define Null(Type) NullHelper<Type>::get_null ()
@ -148,7 +148,7 @@ static inline Type& Crap () {
template <typename QType> template <typename QType>
struct CrapHelper struct CrapHelper
{ {
typedef hb_remove_const (hb_remove_reference (QType)) Type; typedef hb_remove_const<hb_remove_reference<QType> > Type;
static Type & get_crap () { return Crap<Type> (); } static Type & get_crap () { return Crap<Type> (); }
}; };
#define Crap(Type) CrapHelper<Type>::get_crap () #define Crap(Type) CrapHelper<Type>::get_crap ()
@ -171,7 +171,7 @@ struct CrapOrNullHelper<const Type> {
template <typename P> template <typename P>
struct hb_nonnull_ptr_t struct hb_nonnull_ptr_t
{ {
typedef hb_remove_pointer (P) T; typedef hb_remove_pointer<P> T;
hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {} hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {}
T * operator = (T *v_) { return v = v_; } T * operator = (T *v_) { return v = v_; }

File diff suppressed because it is too large Load Diff

View File

@ -426,17 +426,30 @@ hb_ot_tag_to_language (hb_tag_t tag)
if (ot_languages[i].tag == tag) if (ot_languages[i].tag == tag)
return hb_language_from_string (ot_languages[i].language, -1); return hb_language_from_string (ot_languages[i].language, -1);
/* Else return a custom language in the form of "x-hbotABCD" */ /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it
* (if it's not a registered tag, calling hb_ot_tag_from_language on the
* result might not return the same tag as the original tag).
* Else return a custom language in the form of "x-hbotABCD". */
{ {
unsigned char buf[11] = "x-hbot"; char buf[11] = "x-hbot";
char *str = buf;
buf[6] = tag >> 24; buf[6] = tag >> 24;
buf[7] = (tag >> 16) & 0xFF; buf[7] = (tag >> 16) & 0xFF;
buf[8] = (tag >> 8) & 0xFF; buf[8] = (tag >> 8) & 0xFF;
buf[9] = tag & 0xFF; buf[9] = tag & 0xFF;
if (buf[9] == 0x20) if (buf[9] == 0x20)
{
buf[9] = '\0'; buf[9] = '\0';
if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8]))
{
buf[6] = TOLOWER (buf[6]);
buf[7] = TOLOWER (buf[7]);
buf[8] = TOLOWER (buf[8]);
str += 6;
}
}
buf[10] = '\0'; buf[10] = '\0';
return hb_language_from_string ((char *) buf, -1); return hb_language_from_string (str, -1);
} }
} }

View File

@ -281,6 +281,8 @@ test_ot_tag_language (void)
g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE); g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE);
test_language_two_way ("dflt", NULL); test_language_two_way ("dflt", NULL);
test_language_two_way ("ALT", "alt");
test_language_two_way ("ARA", "ar"); test_language_two_way ("ARA", "ar");
test_language_two_way ("AZE", "az"); test_language_two_way ("AZE", "az");
@ -353,7 +355,8 @@ test_ot_tag_language (void)
test_tag_from_language ("ZHS", "zh"); /* Chinese */ test_tag_from_language ("ZHS", "zh"); /* Chinese */
test_tag_from_language ("ZHS", "zh-xx"); test_tag_from_language ("ZHS", "zh-xx");
test_language_two_way ("ABC", "x-hbotabc"); test_language_two_way ("ABC", "abc");
test_language_two_way ("ABCD", "x-hbotabcd");
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc"); test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc"); test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc");
test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd"); test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd");