#include "FRefcnts"
#include <config.h>
#include <string.h>

using namespace Futile;

extern "C" {
void FC_FUNC_(bind_f90_f_reference_counter_copy_constructor, BIND_F90_F_REFERENCE_COUNTER_COPY_CONSTRUCTOR)(FReferenceCounter::f90_f_reference_counter_pointer*,
  const FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_f_associated, BIND_F_ASSOCIATED)(int*,
  const FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_f_ref_null, BIND_F_REF_NULL)(FReferenceCounter::f90_f_reference_counter_pointer*);
void FC_FUNC_(bind_f_ref_new, BIND_F_REF_NEW)(FReferenceCounter::f90_f_reference_counter_pointer*,
  const char*,
  const size_t*,
  const void**,
  size_t);
void FC_FUNC_(bind_f_ref_count, BIND_F_REF_COUNT)(int*,
  const FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_refcnts_errors, BIND_REFCNTS_ERRORS)(void);
void FC_FUNC_(bind_nullify_f_ref, BIND_NULLIFY_F_REF)(FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_f_unref, BIND_F_UNREF)(FReferenceCounter::f90_f_reference_counter*,
  int*);
void FC_FUNC_(bind_f_ref_free, BIND_F_REF_FREE)(FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_f_ref, BIND_F_REF)(FReferenceCounter::f90_f_reference_counter*);
void FC_FUNC_(bind_f_ref_associate, BIND_F_REF_ASSOCIATE)(const FReferenceCounter::f90_f_reference_counter*,
  FReferenceCounter::f90_f_reference_counter*);
}

void Futile::refcnts_errors(void)
{
  FC_FUNC_(bind_refcnts_errors, BIND_REFCNTS_ERRORS)
    ();
}

FReferenceCounter::FReferenceCounter(const FReferenceCounter& other)
{
  FC_FUNC_(bind_f90_f_reference_counter_copy_constructor, BIND_F90_F_REFERENCE_COUNTER_COPY_CONSTRUCTOR)
    (*this, other);
}

bool FReferenceCounter::f_associated(void) const
{
  int out_f_associated;
  FC_FUNC_(bind_f_associated, BIND_F_ASSOCIATED)
    (&out_f_associated, *this);
  return out_f_associated;
}

FReferenceCounter::FReferenceCounter(void)
{
  FC_FUNC_(bind_f_ref_null, BIND_F_REF_NULL)
    (*this);
}

FReferenceCounter::FReferenceCounter(const char* id,
    const void* (*address))
{
  size_t id_chk_len, id_len = id_chk_len = id ? strlen(id) : 0;
  FC_FUNC_(bind_f_ref_new, BIND_F_REF_NEW)
    (*this, id, &id_len, address, id_chk_len);
}

int FReferenceCounter::f_ref_count(void) const
{
  int out_count;
  FC_FUNC_(bind_f_ref_count, BIND_F_REF_COUNT)
    (&out_count, *this);
  return out_count;
}

void FReferenceCounter::nullify_f_ref(void)
{
  FC_FUNC_(bind_nullify_f_ref, BIND_NULLIFY_F_REF)
    (*this);
}

void FReferenceCounter::f_unref(int (*count))
{
  FC_FUNC_(bind_f_unref, BIND_F_UNREF)
    (*this, count);
}

FReferenceCounter::~FReferenceCounter(void)
{
  FC_FUNC_(bind_f_ref_free, BIND_F_REF_FREE)
    (*this);
}

void FReferenceCounter::f_ref(void)
{
  FC_FUNC_(bind_f_ref, BIND_F_REF)
    (*this);
}

void FReferenceCounter::f_ref_associate(FReferenceCounter& dest) const
{
  FC_FUNC_(bind_f_ref_associate, BIND_F_REF_ASSOCIATE)
    (*this, dest);
}

