/*
 * Copyright © 2022 Behdad Esfahbod
 *
 *  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.
 */

#ifndef HB_CPLUSPLUS_HH
#define HB_CPLUSPLUS_HH

#include "hb.h"

#ifdef __cplusplus

#include <functional>
#include <utility>

#if 0
#if !(__cplusplus >= 201103L)
#error "HarfBuzz C++ helpers require C++11"
#endif
#endif

namespace hb {


template <typename T>
struct vtable;

template <typename T>
struct shared_ptr
{
  using element_type = T;

  using v = vtable<T>;

  explicit shared_ptr (T *p = nullptr) : p (p) {}
  shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
  shared_ptr (shared_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
  shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
  shared_ptr& operator = (shared_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
  ~shared_ptr () { v::destroy (p); p = nullptr; }

  T* get() const { return p; }

  void swap (shared_ptr &o)  noexcept { std::swap (p, o.p); }
  friend void swap (shared_ptr &a, shared_ptr &b)  noexcept { std::swap (a.p, b.p); }

  operator T * () const { return p; }
  T& operator * () const { return *get (); }
  T* operator -> () const { return get (); }
  operator bool () const { return p; }
  bool operator == (const shared_ptr &o) const { return p == o.p; }
  bool operator != (const shared_ptr &o) const { return p != o.p; }

  static T* get_empty() { return v::get_empty (); }
  T* reference() { return v::reference (p); }
  void destroy() { v::destroy (p); }
  void set_user_data (hb_user_data_key_t *key,
                      void *value,
                      hb_destroy_func_t destroy,
                      hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); }
  void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }

  private:
  T *p;
};

template<typename T> struct is_shared_ptr : std::false_type {};
template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};

template <typename T>
struct unique_ptr
{
  using element_type = T;

  using v = vtable<T>;

  explicit unique_ptr (T *p = nullptr) : p (p) {}
  unique_ptr (const unique_ptr &o) = delete;
  unique_ptr (unique_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
  unique_ptr& operator = (const unique_ptr &o) = delete;
  unique_ptr& operator = (unique_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
  ~unique_ptr () { v::destroy (p); p = nullptr; }

  T* get() const { return p; }
  T* release () { T* v = p; p = nullptr; return v; }

  void swap (unique_ptr &o)  noexcept { std::swap (p, o.p); }
  friend void swap (unique_ptr &a, unique_ptr &b)  noexcept { std::swap (a.p, b.p); }

  operator T * () const { return p; }
  T& operator * () const { return *get (); }
  T* operator -> () const { return get (); }
  operator bool () { return p; }

  private:
  T *p;
};

template<typename T> struct is_unique_ptr : std::false_type {};
template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};

template <typename T,
          T * (*_get_empty) (void),
          T * (*_reference) (T *),
          void (*_destroy) (T *),
          hb_bool_t (*_set_user_data) (T *,
                                       hb_user_data_key_t *,
                                       void *,
                                       hb_destroy_func_t,
                                       hb_bool_t),
          void * (*_get_user_data) (const T *,
                                    hb_user_data_key_t *)>
struct vtable_t
{
  static constexpr auto get_empty = _get_empty;
  static constexpr auto reference = _reference;
  static constexpr auto destroy = _destroy;
  static constexpr auto set_user_data = _set_user_data;
  static constexpr auto get_user_data = _get_user_data;
};

#define HB_DEFINE_VTABLE(name) \
        template<> \
        struct vtable<hb_##name##_t> \
             : vtable_t<hb_##name##_t, \
                        &hb_##name##_get_empty, \
                        &hb_##name##_reference, \
                        &hb_##name##_destroy, \
                        &hb_##name##_set_user_data, \
                        &hb_##name##_get_user_data> {}

HB_DEFINE_VTABLE (buffer);
HB_DEFINE_VTABLE (blob);
HB_DEFINE_VTABLE (face);
HB_DEFINE_VTABLE (font);
HB_DEFINE_VTABLE (font_funcs);
HB_DEFINE_VTABLE (map);
HB_DEFINE_VTABLE (set);
HB_DEFINE_VTABLE (shape_plan);
HB_DEFINE_VTABLE (unicode_funcs);
HB_DEFINE_VTABLE (draw_funcs);
HB_DEFINE_VTABLE (paint_funcs);

#undef HB_DEFINE_VTABLE


#ifdef HB_SUBSET_H

#define HB_DEFINE_VTABLE(name) \
        template<> \
        struct vtable<hb_##name##_t> \
             : vtable_t<hb_##name##_t, \
                        nullptr, \
                        &hb_##name##_reference, \
                        &hb_##name##_destroy, \
                        &hb_##name##_set_user_data, \
                        &hb_##name##_get_user_data> {}


HB_DEFINE_VTABLE (subset_input);
HB_DEFINE_VTABLE (subset_plan);

#undef HB_DEFINE_VTABLE

#endif


} // namespace hb

/* Workaround for GCC < 7, see:
 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
 * https://stackoverflow.com/a/25594741 */
namespace std {


template<typename T>
struct hash<hb::shared_ptr<T>>
{
    std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
    {
        std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
        return h;
    }
};

template<typename T>
struct hash<hb::unique_ptr<T>>
{
    std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
    {
        std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
        return h;
    }
};


} // namespace std

#endif /* __cplusplus */

#endif /* HB_CPLUSPLUS_HH */
