Add HB_FUNCOBJ()

Fixes https://github.com/harfbuzz/harfbuzz/issues/1651
This commit is contained in:
Behdad Esfahbod 2019-04-15 15:39:03 -04:00
parent 60be1450ad
commit 02d864aa26
4 changed files with 63 additions and 50 deletions

View File

@ -1,5 +1,6 @@
/* /*
* Copyright © 2017 Google, Inc. * Copyright © 2017 Google, Inc.
* Copyright © 2019 Google, Inc.
* *
* This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
* *
@ -22,6 +23,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* Google Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/ */
#ifndef HB_ALGS_HH #ifndef HB_ALGS_HH
@ -54,19 +56,19 @@ struct
/* Knuth's multiplicative method: */ /* Knuth's multiplicative method: */
return (uint32_t) v * 2654435761u; return (uint32_t) v * 2654435761u;
} }
} static const hb_hash HB_UNUSED; } HB_FUNCOBJ (hb_hash);
static const struct struct
{ {
template <typename T> T template <typename T> T
operator () (const T& v) const { return v; } operator () (const T& v) const { return v; }
} hb_identity HB_UNUSED; } HB_FUNCOBJ (hb_identity);
static const struct struct
{ {
template <typename T> bool template <typename T> bool
operator () (const T& v) const { return bool (v); } operator () (const T& v) const { return bool (v); }
} hb_bool HB_UNUSED; } HB_FUNCOBJ (hb_bool);
template <typename T1, typename T2> template <typename T1, typename T2>
struct hb_pair_t struct hb_pair_t
@ -86,28 +88,28 @@ struct hb_pair_t
template <typename T1, typename T2> static inline hb_pair_t<T1, T2> template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); } hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
static const struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).first) template <typename Pair> decltype (hb_declval (Pair).first)
operator () (const Pair& pair) const { return pair.first; } operator () (const Pair& pair) const { return pair.first; }
} hb_first HB_UNUSED; } HB_FUNCOBJ (hb_first);
static const struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).second) template <typename Pair> decltype (hb_declval (Pair).second)
operator () (const Pair& pair) const { return pair.second; } operator () (const Pair& pair) const { return pair.second; }
} hb_second HB_UNUSED; } HB_FUNCOBJ (hb_second);
static const struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> T
operator () (const T& a, const T2& b) const { return a <= b ? a : b; } operator () (const T& a, const T2& b) const { return a <= b ? a : b; }
} hb_min HB_UNUSED; } HB_FUNCOBJ (hb_min);
static const struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> T
operator () (const T& a, const T2& b) const { return a >= b ? a : b; } operator () (const T& a, const T2& b) const { return a >= b ? a : b; }
} hb_max HB_UNUSED; } HB_FUNCOBJ (hb_max);
/* /*

View File

@ -1,5 +1,6 @@
/* /*
* Copyright © 2018 Google, Inc. * Copyright © 2018 Google, Inc.
* Copyright © 2019 Google, Inc.
* *
* This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
* *
@ -22,6 +23,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* Google Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/ */
#ifndef HB_ITER_HH #ifndef HB_ITER_HH
@ -130,7 +132,7 @@ struct hb_iter_t
template <typename> struct hb_array_t; template <typename> struct hb_array_t;
static const struct struct
{ {
template <typename T> template <typename T>
hb_iter_t (T) hb_iter_t (T)
@ -147,7 +149,7 @@ static const struct
operator () (Type (&array)[length]) const operator () (Type (&array)[length]) const
{ return hb_array_t<Type> (array, length); } { return hb_array_t<Type> (array, length); }
} hb_iter HB_UNUSED; } HB_FUNCOBJ (hb_iter);
/* Mixin to fill in what the subclass doesn't provide. */ /* Mixin to fill in what the subclass doesn't provide. */
@ -298,13 +300,13 @@ struct hb_map_iter_factory_t
private: private:
Proj f; Proj f;
}; };
static const struct struct
{ {
template <typename Proj> template <typename Proj>
hb_map_iter_factory_t<Proj> hb_map_iter_factory_t<Proj>
operator () (Proj&& f) const operator () (Proj&& f) const
{ return hb_map_iter_factory_t<Proj> (f); } { return hb_map_iter_factory_t<Proj> (f); }
} hb_map HB_UNUSED; } HB_FUNCOBJ (hb_map);
template <typename Iter, typename Pred, typename Proj, template <typename Iter, typename Pred, typename Proj,
hb_enable_if (hb_is_iterator (Iter))> hb_enable_if (hb_is_iterator (Iter))>
@ -342,14 +344,14 @@ struct hb_filter_iter_factory_t
Pred p; Pred p;
Proj f; Proj f;
}; };
static const struct struct
{ {
template <typename Pred = decltype ((hb_bool)), template <typename Pred = decltype ((hb_bool)),
typename Proj = decltype ((hb_identity))> typename Proj = decltype ((hb_identity))>
hb_filter_iter_factory_t<Pred, Proj> hb_filter_iter_factory_t<Pred, Proj>
operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const
{ return hb_filter_iter_factory_t<Pred, Proj> (p, f); } { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
} hb_filter HB_UNUSED; } HB_FUNCOBJ (hb_filter);
template <typename Redu, typename InitT> template <typename Redu, typename InitT>
struct hb_reduce_t struct hb_reduce_t
@ -372,13 +374,13 @@ struct hb_reduce_t
Redu r; Redu r;
InitT init_value; InitT init_value;
}; };
static const struct struct
{ {
template <typename Redu, typename InitT> template <typename Redu, typename InitT>
hb_reduce_t<Redu, InitT> hb_reduce_t<Redu, InitT>
operator () (Redu&& r, InitT init_value) const operator () (Redu&& r, InitT init_value) const
{ return hb_reduce_t<Redu, InitT> (r, init_value); } { return hb_reduce_t<Redu, InitT> (r, init_value); }
} hb_reduce HB_UNUSED; } HB_FUNCOBJ (hb_reduce);
/* hb_zip() */ /* hb_zip() */
@ -411,14 +413,14 @@ struct hb_zip_iter_t :
A a; A a;
B b; B b;
}; };
static const struct struct
{ {
template <typename A, typename B, template <typename A, typename B,
hb_enable_if (hb_is_iterable (A) && hb_is_iterable (B))> hb_enable_if (hb_is_iterable (A) && hb_is_iterable (B))>
hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)>
operator () (A& a, B &b) const operator () (A& a, B &b) const
{ return hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> (hb_iter (a), hb_iter (b)); } { return hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> (hb_iter (a), hb_iter (b)); }
} hb_zip HB_UNUSED; } HB_FUNCOBJ (hb_zip);
/* hb_enumerate */ /* hb_enumerate */
@ -446,14 +448,14 @@ struct hb_enumerate_iter_t :
unsigned i; unsigned i;
Iter it; Iter it;
}; };
static const struct struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
hb_enumerate_iter_t<hb_iter_t (Iterable)> hb_enumerate_iter_t<hb_iter_t (Iterable)>
operator () (Iterable& it) const operator () (Iterable& it) const
{ return hb_enumerate_iter_t<hb_iter_t (Iterable)> (hb_iter (it)); } { return hb_enumerate_iter_t<hb_iter_t (Iterable)> (hb_iter (it)); }
} hb_enumerate HB_UNUSED; } HB_FUNCOBJ (hb_enumerate);
/* hb_apply() */ /* hb_apply() */
@ -474,7 +476,7 @@ struct hb_apply_t
private: private:
Appl a; Appl a;
}; };
static const struct struct
{ {
template <typename Appl> hb_apply_t<Appl> template <typename Appl> hb_apply_t<Appl>
operator () (Appl&& a) const operator () (Appl&& a) const
@ -483,7 +485,7 @@ static const struct
template <typename Appl> hb_apply_t<Appl&> template <typename Appl> hb_apply_t<Appl&>
operator () (Appl *a) const operator () (Appl *a) const
{ return hb_apply_t<Appl&> (*a); } { return hb_apply_t<Appl&> (*a); }
} hb_apply HB_UNUSED; } HB_FUNCOBJ (hb_apply);
/* hb_sink() */ /* hb_sink() */
@ -504,7 +506,7 @@ struct hb_sink_t
private: private:
Sink s; Sink s;
}; };
static const struct struct
{ {
template <typename Sink> hb_sink_t<Sink> template <typename Sink> hb_sink_t<Sink>
operator () (Sink&& s) const operator () (Sink&& s) const
@ -513,11 +515,11 @@ static const struct
template <typename Sink> hb_sink_t<Sink&> template <typename Sink> hb_sink_t<Sink&>
operator () (Sink *s) const operator () (Sink *s) const
{ return hb_sink_t<Sink&> (*s); } { return hb_sink_t<Sink&> (*s); }
} hb_sink HB_UNUSED; } HB_FUNCOBJ (hb_sink);
/* hb-drain: hb_sink to void / blackhole / /dev/null. */ /* hb-drain: hb_sink to void / blackhole / /dev/null. */
static const struct struct
{ {
template <typename Iter, template <typename Iter,
hb_enable_if (hb_is_iterator (Iter))> hb_enable_if (hb_is_iterator (Iter))>
@ -527,7 +529,7 @@ static const struct
for (; it; ++it) for (; it; ++it)
(void) *it; (void) *it;
} }
} hb_drain HB_UNUSED; } HB_FUNCOBJ (hb_drain);
/* hb_unzip(): unzip and sink to two sinks. */ /* hb_unzip(): unzip and sink to two sinks. */
@ -553,7 +555,7 @@ struct hb_unzip_t
Sink1 s1; Sink1 s1;
Sink2 s2; Sink2 s2;
}; };
static const struct struct
{ {
template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2> template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2>
operator () (Sink1&& s1, Sink2&& s2) const operator () (Sink1&& s1, Sink2&& s2) const
@ -562,12 +564,12 @@ static const struct
template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&> template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&>
operator () (Sink1 *s1, Sink2 *s2) const operator () (Sink1 *s1, Sink2 *s2) const
{ return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); } { return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); }
} hb_unzip HB_UNUSED; } HB_FUNCOBJ (hb_unzip);
/* hb-all, hb-any, hb-none. */ /* hb-all, hb-any, hb-none. */
static const struct struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -579,9 +581,8 @@ static const struct
return false; return false;
return true; return true;
} }
} hb_all HB_UNUSED; } HB_FUNCOBJ (hb_all);
struct
static const struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -593,9 +594,8 @@ static const struct
return true; return true;
return false; return false;
} }
} hb_any HB_UNUSED; } HB_FUNCOBJ (hb_any);
struct
static const struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -607,7 +607,7 @@ static const struct
return false; return false;
return true; return true;
} }
} hb_none HB_UNUSED; } HB_FUNCOBJ (hb_none);
/* /*
* Algorithms operating on iterators. * Algorithms operating on iterators.

View File

@ -34,18 +34,22 @@
* C++ template meta-programming & fundamentals used with them. * C++ template meta-programming & fundamentals used with them.
*/ */
#define HB_FUNCOBJ(x) static_const x HB_UNUSED
template <typename T> static inline T* struct
hb_addressof (const T& arg)
{ {
template <typename T>
T* operator () (const T& arg) const
{
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wcast-align"
/* https://en.cppreference.com/w/cpp/memory/addressof */ /* https://en.cppreference.com/w/cpp/memory/addressof */
return reinterpret_cast<T*>( return reinterpret_cast<T*> (
&const_cast<char&>( &const_cast<char&> (
reinterpret_cast<const volatile char&>(arg))); reinterpret_cast<const volatile char&> (arg)));
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
} HB_FUNCOBJ (hb_addressof);
template <typename T> static inline T hb_declval (); template <typename T> static inline T hb_declval ();
#define hb_declval(T) (hb_declval<T> ()) #define hb_declval(T) (hb_declval<T> ())
@ -63,13 +67,13 @@ template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { valu
#define hb_remove_pointer(T) typename hb_match_pointer<T>::type #define hb_remove_pointer(T) 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
static const struct struct
{ {
template <typename T> template <typename T>
T operator () (T v) const { return v; } T operator () (T v) const { return v; }
template <typename T> template <typename T>
T& operator () (T *v) const { return *v; } T& operator () (T *v) const { return *v; }
} hb_deref_pointer HB_UNUSED; } HB_FUNCOBJ (hb_deref_pointer);
/* std::move and std::forward */ /* std::move and std::forward */

View File

@ -260,6 +260,13 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
# endif # endif
#endif #endif
/* https://github.com/harfbuzz/harfbuzz/issues/1651 */
#if defined(__clang__) && __clang_major__ < 10
#define static_const static
#else
#define static_const static const
#endif
#if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(__GNUC__) && (__GNUC__ >= 3)
#define HB_FUNC __PRETTY_FUNCTION__ #define HB_FUNC __PRETTY_FUNCTION__
#elif defined(_MSC_VER) #elif defined(_MSC_VER)