/*
 * Copyright © 2011  Google, Inc.
 * 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.
 *
 * Google Author(s): Behdad Esfahbod
 */

/* This file tests that all headers can be included from C++ files,
 * as well as test the C++ API. */

#define NO_MAIN
#include "test-c.c"
#undef NO_MAIN

#ifdef HAVE_DIRECTWRITE
#include <hb-directwrite.h>
#endif


/* Test C++ API. */

#include "hb-cplusplus.hh"

#include <functional>
#include <utility>

static void
test_smart_ptrs (void)
{
  hb_buffer_t *b = hb_buffer_create ();
  hb::shared_ptr<hb_buffer_t> pb {b};

  /* Test copy-construction. */
  g_assert_true (bool (pb));
  hb::shared_ptr<hb_buffer_t> pb2 {pb};
  g_assert_true (bool (pb2));
  g_assert_true (bool (pb));

  /* Test move-construction. */
  g_assert_true (bool (pb2));
  hb::shared_ptr<hb_buffer_t> pb4 {std::move (pb2)};
  g_assert_true (!bool (pb2));
  g_assert_true (bool (pb4));

  /* Test copy-assignment. */
  hb::shared_ptr<hb_buffer_t> pb3;
  g_assert_true (!bool (pb3));
  pb3 = pb;
  g_assert_true (bool (pb3));
  g_assert_true (bool (pb));

  /* Test move-assignment. */
  g_assert_true (bool (pb));
  pb2 = std::move (pb);
  g_assert_true (!bool (pb));

  pb.reference ();
  pb.destroy ();

  pb3.reference ();
  pb3.destroy ();

  pb3.swap (pb4);

  hb_user_data_key_t key;
  pb.set_user_data (&key, b, nullptr, true);
  (void) pb.get_user_data (&key);

  hb::unique_ptr<hb_buffer_t> pb5 {pb3.reference ()};


  /* Test that shared_ptr / unique_ptr are std::hash'able, and that they
   * return the same hash (which is the underlying pointer's hash. */
  std::hash<hb_buffer_t *> hash {};
  std::hash<hb::shared_ptr<hb_buffer_t>> hash2 {};
  std::hash<hb::unique_ptr<hb_buffer_t>> hash3 {};

  g_assert_true (hash (b) == hash2 (pb4));
  g_assert_true (hash2 (pb4) == hash2 (pb2));
  g_assert_true (hash (b) == hash3 (pb5));

  g_assert_true (pb != pb.get_empty ());
  g_assert_true (pb != pb2);
}

int
main (int argc, char **argv)
{
  hb_test_init (&argc, &argv);

  hb_test_add (test_smart_ptrs);

  return hb_test_run ();
}
