diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index da6e941c9..9edd2be56 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -590,18 +590,51 @@ struct BEInt * Lazy loaders. */ +template +struct hb_data_wrapper_t +{ + static_assert (WheresData > 0, ""); + + inline Data * get_data (void) const + { + return *(((Data **) this) - WheresData); + } + + template + inline Stored * call_create (void) const + { + Data *data = this->get_data (); + return likely (data) ? Subclass::create (data) : nullptr; + } +}; +template <> +struct hb_data_wrapper_t +{ + template + inline Stored * call_create (void) const + { + return Subclass::create (); + } +}; + template -struct hb_lazy_loader_t +struct hb_lazy_loader_t : hb_data_wrapper_t { - static_assert (WheresData > 0, ""); - inline void init0 (void) {} /* Init, when memory is already set to 0. No-op for us. */ inline void init (void) { instance.set_relaxed (nullptr); } inline void fini (void) { destroy (instance.get ()); } + + inline Stored * create (void) const + { + Stored *p = this->template call_create (); + if (unlikely (!p)) + p = const_cast (Subclass::get_null ()); + return p; + } static inline void destroy (Stored *p) { if (p && p != Subclass::get_null ()) @@ -622,11 +655,7 @@ struct hb_lazy_loader_t Stored *p = this->instance.get (); if (unlikely (!p)) { - Data *data = get_data (); - if (likely (data)) - p = Subclass::create (data); - if (unlikely (!p)) - p = const_cast (Subclass::get_null ()); + p = create (); assert (p); if (unlikely (!this->instance.cmpexch (nullptr, p))) {