/*
 * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
 * Copyright © 2012,2018  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 * Google Author(s): Behdad Esfahbod
 */

#ifndef HB_MACHINERY_HH
#define HB_MACHINERY_HH

#include "hb.hh"
#include "hb-blob.hh"

#include "hb-dispatch.hh"
#include "hb-sanitize.hh"


/*
 * Casts
 */

/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
 * location pointed to by P plus Ofs bytes. */
template<typename Type>
static inline const Type& StructAtOffset(const void *P, unsigned int offset)
{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
template<typename Type>
static inline Type& StructAtOffset(void *P, unsigned int offset)
{ return * reinterpret_cast<Type*> ((char *) P + offset); }
template<typename Type>
static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int offset)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
  return * reinterpret_cast<const Type*> ((const char *) P + offset);
#pragma GCC diagnostic pop
}
template<typename Type>
static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
  return * reinterpret_cast<Type*> ((char *) P + offset);
#pragma GCC diagnostic pop
}

/* StructAfter<T>(X) returns the struct T& that is placed after X.
 * Works with X of variable size also.  X must implement get_size().
 * Any extra arguments are forwarded to get_size, so for example
 * it can work with UnsizedArrayOf<> as well. */
template <typename Type, typename TObject, typename ...Ts>
static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN((
  StructAtOffset<Type>(&X, X.get_size(std::forward<Ts> (args)...))
))
/* The is_const shenanigans is to avoid ambiguous overload with gcc-8.
 * It disables this path when TObject is const.
 * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */
template <typename Type, typename TObject, typename ...Ts>
static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN((
  sizeof(int[std::is_const<TObject>::value ? -1 : +1]) > 0 ?
  StructAtOffset<Type>(&X, X.get_size(std::forward<Ts> (args)...))
  : *reinterpret_cast<Type*> (0)
))


/*
 * Size checking
 */

/* Size signifying variable-sized array */
#ifndef HB_VAR_ARRAY
#define HB_VAR_ARRAY 1
#endif

/* Check _assertion in a method environment */
#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
  void _instance_assertion_on_line_##_line () const \
  { static_assert ((_assertion), ""); }
# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)

/* Check that _code compiles in a method environment */
#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
  void _compiles_assertion_on_line_##_line () const \
  { _code; }
# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)


#define DEFINE_SIZE_STATIC(size) \
  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \
  unsigned int get_size () const { return (size); } \
  static constexpr unsigned null_size = (size); \
  static constexpr unsigned min_size = (size); \
  static constexpr unsigned static_size = (size)

#define DEFINE_SIZE_UNION(size, _member) \
  DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size) \
  DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)) \
  static constexpr unsigned null_size = (size); \
  static constexpr unsigned min_size = (size)

#define DEFINE_SIZE_MIN(size) \
  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
  static constexpr unsigned null_size = (size); \
  static constexpr unsigned min_size = (size)

#define DEFINE_SIZE_UNBOUNDED(size) \
  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
  static constexpr unsigned min_size = (size)

#define DEFINE_SIZE_ARRAY(size, array) \
  DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + (HB_VAR_ARRAY+0) * sizeof ((array)[0])) \
  static constexpr unsigned null_size = (size); \
  static constexpr unsigned min_size = (size)

#define DEFINE_SIZE_ARRAY_SIZED(size, array) \
  unsigned int get_size () const { return (size - (array).min_size + (array).get_size ()); } \
  DEFINE_SIZE_ARRAY(size, array)


/*
 * Lazy loaders.
 *
 * The lazy-loaders are thread-safe pointer-like objects that create their
 * instead on-demand.  They also support access to a "data" object that is
 * necessary for creating their instance.  The data object, if specified,
 * is accessed via pointer math, located at a location before the position
 * of the loader itself.  This avoids having to store a pointer to data
 * for every lazy-loader.  Multiple lazy-loaders can access the same data.
 */

template <typename Data, unsigned int WheresData>
struct hb_data_wrapper_t
{
  static_assert (WheresData > 0, "");

  Data * get_data () const
  { return *(((Data **) (void *) this) - WheresData); }

  bool is_inert () const { return !get_data (); }

  template <typename Stored, typename Subclass>
  Stored * call_create () const { return Subclass::create (get_data ()); }
};
template <>
struct hb_data_wrapper_t<void, 0>
{
  bool is_inert () const { return false; }

  template <typename Stored, typename Funcs>
  Stored * call_create () const { return Funcs::create (); }
};

template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
template <typename T2> struct hb_non_void_t<void, T2> { typedef T2 value; };

template <typename Returned,
	  typename Subclass = void,
	  typename Data = void,
	  unsigned int WheresData = 0,
	  typename Stored = Returned>
struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
{
  typedef typename hb_non_void_t<Subclass,
				 hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored>
				>::value Funcs;

  hb_lazy_loader_t () = default;
  hb_lazy_loader_t (const hb_lazy_loader_t &other) = delete;

  void init0 () {} /* Init, when memory is already set to 0. No-op for us. */
  void init ()  { instance.set_relaxed (nullptr); }
  void fini ()  { do_destroy (instance.get_acquire ()); init (); }

  void free_instance ()
  {
  retry:
    Stored *p = instance.get_acquire ();
    if (unlikely (p && !cmpexch (p, nullptr)))
      goto retry;
    do_destroy (p);
  }

  static void do_destroy (Stored *p)
  {
    if (p && p != const_cast<Stored *> (Funcs::get_null ()))
      Funcs::destroy (p);
  }

  const Returned * operator -> () const { return get (); }
  template <typename U = Returned, hb_enable_if (!hb_is_same (U, void))>
  const U & operator * () const  { return *get (); }
  explicit operator bool () const
  { return get_stored () != Funcs::get_null (); }
  template <typename C> operator const C * () const { return get (); }

  Stored * get_stored () const
  {
  retry:
    Stored *p = this->instance.get_acquire ();
    if (unlikely (!p))
    {
      if (unlikely (this->is_inert ()))
	return const_cast<Stored *> (Funcs::get_null ());

      p = this->template call_create<Stored, Funcs> ();
      if (unlikely (!p))
	p = const_cast<Stored *> (Funcs::get_null ());

      if (unlikely (!cmpexch (nullptr, p)))
      {
	do_destroy (p);
	goto retry;
      }
    }
    return p;
  }
  Stored * get_stored_relaxed () const
  {
    return this->instance.get_relaxed ();
  }

  bool cmpexch (Stored *current, Stored *value) const
  {
    /* This function can only be safely called directly if no
     * other thread is accessing. */
    return this->instance.cmpexch (current, value);
  }

  const Returned * get () const { return Funcs::convert (get_stored ()); }
  const Returned * get_relaxed () const { return Funcs::convert (get_stored_relaxed ()); }
  Returned * get_unconst () const { return const_cast<Returned *> (Funcs::convert (get_stored ())); }

  /* To be possibly overloaded by subclasses. */
  static Returned* convert (Stored *p) { return p; }

  /* By default null/init/fini the object. */
  static const Stored* get_null () { return &Null (Stored); }
  static Stored *create (Data *data)
  {
    Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
    if (likely (p))
      p = new (p) Stored (data);
    return p;
  }
  static Stored *create ()
  {
    Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
    if (likely (p))
      p = new (p) Stored ();
    return p;
  }
  static void destroy (Stored *p)
  {
    p->~Stored ();
    hb_free (p);
  }

  private:
  /* Must only have one pointer. */
  mutable hb_atomic_t<Stored *> instance;
};

/* Specializations. */

template <typename T, unsigned int WheresFace>
struct hb_face_lazy_loader_t : hb_lazy_loader_t<T,
						hb_face_lazy_loader_t<T, WheresFace>,
						hb_face_t, WheresFace>
{
  // Hack; have them here for API parity with hb_table_lazy_loader_t
  hb_blob_t *get_blob () { return this->get ()->get_blob (); }
};

template <typename T, unsigned int WheresFace, bool core=false>
struct hb_table_lazy_loader_t : hb_lazy_loader_t<T,
						 hb_table_lazy_loader_t<T, WheresFace, core>,
						 hb_face_t, WheresFace,
						 hb_blob_t>
{
  static hb_blob_t *create (hb_face_t *face)
  {
    hb_sanitize_context_t c;
    if (core)
      c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs
    return c.reference_table<T> (face);
  }
  static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }

  static const hb_blob_t *get_null ()
  { return hb_blob_get_empty (); }

  static const T* convert (const hb_blob_t *blob)
  { return blob->as<T> (); }

  hb_blob_t* get_blob () const { return this->get_stored (); }
};

#define HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T(Type) \
  template <typename Subclass> \
  struct hb_##Type##_funcs_lazy_loader_t : hb_lazy_loader_t<hb_##Type##_funcs_t, Subclass> \
  { \
    static void destroy (hb_##Type##_funcs_t *p) \
    { hb_##Type##_funcs_destroy (p); } \
    static const hb_##Type##_funcs_t *get_null () \
    { return hb_##Type##_funcs_get_empty (); } \
  }

HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (font);
HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (unicode);
HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (draw);
HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (paint);

#undef HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T


#endif /* HB_MACHINERY_HH */
