/* libsizzle/uvector64.c - 64-bit uniform vector functions
 
  Copyright (C) 2000 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
 
  This is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.
  
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this package; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */

#if HAVE_CONFIG_H
# include <config.h>
#endif 

#if ENABLE_UVECTOR

#include <stdio.h>

#if ENABLE_NLS
# include <libintl.h>
# define _(String) gettext(String)
#else
# define _(String) (String)
#endif

#include "alloc.h"
#include "node.h"
#include "eval.h"
#include "validate.h"
#include "capi.h"
#include "port.h"
#include "list.h"
#include "uvector64.h"

/* This holds the tag used for vector objects.  */
#if HAVE_LONG_LONG
zzz_object_t zzz_tagged_type_s64vector;
zzz_object_t zzz_tagged_type_u64vector;
#endif /* HAVE_LONG_LONG */

#if HAVE_LONG_LONG

/*:doc
  s64vector?
  (s64vector? obj) => boolean
  Return @code{#t}, if @var{obj} is a homogenous signed 64-bit vector,
  @code{#f} otherwise.
  doc:*/
#define FUNC_NAME "s64vector?"
static result_t
s64vector_p_func (zzz_scm_t env, zzz_scm_t obj, zzz_scm_t * result)
{
  if (s64vector_p (obj))
    *result = zzz_true_value;
  else
    *result = zzz_false_value;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  make-s64vector
  (make-s64vector len [fill]) => vector
  Create a homogenous signed 64-bit vector capable of holding @var{len}
  elements and initializes the vector fields to @var{fill}.  If @var{fill} is
  omitted, the contents of the vector is undefined.
  doc:*/
#define FUNC_NAME "make-s64vector"
static result_t
make_s64vector_func (zzz_scm_t env, zzz_scm_t k, zzz_scm_t fill,
		    zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  int len;
  signed __INT64__ f;

  CHECK_TYPE (1, integer_p (k), zzz_integer_type_name);
  CHECK_RANGE (1, integer_val (k) >= 0, 
	       _("value greater than or equal to zero"));
  if (fill == zzz_undefined)
    f = 0;
  else
    {
      CHECK_TYPE (2, integer_p (fill), zzz_integer_type_name);
      f = integer_val (fill);
    }
  len = integer_val (k);
  *result = zzz_make_s64vector (len);
  while (--len >= 0)
    s64vector_val (*result)[len] = f;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector
  (s64vector num ...) => vector
  Create a homogenous signed 64-bit vector holding all the signed 64-bit
  values @var{num}s passed as arguments.
  doc:*/
#define FUNC_NAME "s64vector"
static result_t
s64vector_func (zzz_scm_t env, zzz_scm_t param, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t temp;
  zzz_scm_t res = NULL;
  int len;

  /* Param is guaranteed to be a proper list when we get here.  */
  len = zzz_list_length (param);
  res = zzz_make_s64vector (len);
  len = 0;
  temp = param;
  while (cons_p (temp))
    {
      CHECK_TYPE (len + 1, integer_p (car (temp)), zzz_integer_type_name);
      s64vector_val (res)[len] = integer_val (car (temp));
      temp = cdr (temp);
      len++;
    }
  *result = res;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector-length
  (s64vector-length vec) => integer
  Return the number of elements the homogenous signed 64-bit vector @var{vec}
  can hold.
  doc:*/
#define FUNC_NAME "s64vector-length"
static result_t
s64vector_length_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;

  CHECK_TYPE (1, s64vector_p (vec), zzz_s64vector_type_name);
  *result = zzz_make_integer (s64vector_len (vec));
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector-ref
  (s64vector-ref vec n) => object
  Return the signed 64-bit value stored at index @var{n} in the vector
  homogenous signed 64-bit @var{vec}.  The index @var{n} is zero-based.
  doc:*/
#define FUNC_NAME "s64vector-ref"
static result_t
s64vector_ref_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t k,
  zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned long index;

  CHECK_TYPE (1, s64vector_p (vec), zzz_s64vector_type_name);
  CHECK_TYPE (2, integer_p (k), zzz_integer_type_name);
  index = integer_val (k);
  CHECK_RANGE (2, index < s64vector_len (vec), _("valid vector index"));
  *result = zzz_make_integer ((long) s64vector_val (vec)[index]);
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector-set!
  (s64vector-set! vec n num) => *undefined*
  Store the signed 64-bit value at index @var{n} into the signed 64-bit vector
  @var{vec}.  The index @var{n} is zero-based.
  doc:*/
#define FUNC_NAME "s64vector-set!"
static result_t
s64vector_set_x_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t k, zzz_scm_t obj,
		     zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned long index;

  CHECK_TYPE (1, s64vector_p (vec), zzz_s64vector_type_name);
  CHECK_TYPE (1, !ro_s64vector_p (vec), _("mutable vector"));
  CHECK_TYPE (2, integer_p (k), zzz_integer_type_name);
  CHECK_TYPE (3, integer_p (obj), zzz_integer_type_name);
  index = integer_val (k);
  CHECK_RANGE (2, index < s64vector_len (vec), _("valid vector index"));
  s64vector_val (vec)[index] = integer_val (obj);
  *result = zzz_unspecified;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector->list
  (s64vector->list vec) => list
  Return a list containing the elements of the signed 64-bit vector @var{vec}.
  doc:*/
#define FUNC_NAME "s64vector->list"
static result_t
s64vector_to_list_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t res;
  unsigned len;

  CHECK_TYPE (1, s64vector_p (vec), zzz_s64vector_type_name);
  len = s64vector_len (vec);
  res = NULL;
  while (len-- > 0)
    res = zzz_cons (zzz_make_integer ((long) s64vector_val (vec)[len]), res);
  *result = res;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  list->s64vector
  (list->s64vector list) => vector
  Return a signed 64-bit vector containing the elements of the list @var{list}.
  doc:*/
#define FUNC_NAME "list->s64vector"
static result_t
list_to_s64vector_func (zzz_scm_t env, zzz_scm_t list, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t vec = NULL;
  int len = 0;

  CHECK_TYPE (1, zzz_list_length (list) >= 0, zzz_proper_list_type_name);
  /* Param is guaranteed to be a proper list when we get here.  */
  len = zzz_list_length (list);
  vec = zzz_make_s64vector (len);
  len = 0;
  while (cons_p (list))
    {
      CHECK_TYPE (len + 1, integer_p (car (list)), zzz_integer_type_name);
      s64vector_val (vec)[len] = integer_val (car (list));
      len++;
      list = cdr (list);
    }
  *result = vec;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  s64vector-fill!
  (s64vector-fill! vec num) => *undefined*
  Store signed 64-bit value @var{num} in all elements of the signed 64-bit
  vector @var{vec}, overwriting the old contents of @var{vec}.
  doc:*/
#define FUNC_NAME "s64vector-fill!"
static result_t
s64vector_fill_x_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t fill,
		    zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned len;

  CHECK_TYPE (1, s64vector_p (vec), zzz_s64vector_type_name);
  CHECK_TYPE (1, !ro_s64vector_p (vec), _("mutable vector"));
  CHECK_TYPE (2, integer_p (fill), zzz_integer_type_name);
  len = s64vector_len (vec);
  while (len-- > 0)
    s64vector_val (vec)[len] = integer_val (fill);
  *result = zzz_unspecified;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/* Constructor function for vector objects.  Expects the desired
   vector len as a long value in @var{data0}.  Returns @var{tagged}.  */
static void *
s64vector_constructor (zzz_tagged_t tagged, void * data0,
		    void * data1, void * data2)
{
  unsigned long len = (long) data0;
  signed __INT64__ * vec;
  unsigned long x;

  vec = zzz_malloc (sizeof (signed __INT64__) * len);
  for (x = 0; x < len; x++)
    vec[x] = 0;
  tagged->fill[1] = (zzz_object_t) vec;
  tagged->fill[2] = (zzz_object_t) len;
  return tagged;
}

static void
s64vector_print (zzz_scm_t port, zzz_tagged_t tagged, zzz_print_state_t state)
{
  zzz_scm_t result;
  signed __INT64__ * vec = s64vector_val (tagged);
  unsigned long len = s64vector_len (tagged);
  unsigned long x;
  char buf[64];
  int l;

  zzz_port_puts (port, "#s64(", 5, &result);
  for (x = 0; x < len; x++)
    {
      l = sprintf (buf, "%lld", vec[x]);
      zzz_port_puts (port, buf, l, &result);
      if (x < len - 1)
	zzz_port_putc (' ', port, &result);
    }
  zzz_port_putc (')', port, &result);
}

static void
s64vector_free (zzz_tagged_t tagged)
{
  zzz_free (s64vector_val (tagged),
	    sizeof (signed __INT64__) * s64vector_len (tagged));
}

static int
s64vector_equal (zzz_tagged_t tagged0, zzz_tagged_t tagged1)
{
  signed __INT64__ * vec1 = s64vector_val (tagged0);
  unsigned long len1 = s64vector_len (tagged0);
  signed __INT64__ * vec2 = s64vector_val (tagged1);
  unsigned long len2 = s64vector_len (tagged1);
  unsigned long x;

  if (len1 != len2)
    return 0;
  for (x = 0; x < len1; x++)
    {
      if (vec1[x] != vec2[x])
	return 0;
    }
  return 1;
}

/*:doc
  u64vector?
  (u64vector? obj) => boolean
  Return @code{#t}, if @var{obj} is a homogenous unsigned 64-bit vector, 
  @code{#f} otherwise.
  doc:*/
#define FUNC_NAME "u64vector?"
static result_t
u64vector_p_func (zzz_scm_t env, zzz_scm_t obj, zzz_scm_t * result)
{
  if (u64vector_p (obj))
    *result = zzz_true_value;
  else
    *result = zzz_false_value;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  make-u64vector
  (make-u64vector len [fill]) => vector
  Create a homogenous unsigned 64-bit vector capable of holding @var{len}
  elements and initializes the vector fields to @var{fill}.  If @var{fill} is
  omitted, the contents of the vector is undefined.
  doc:*/
#define FUNC_NAME "make-u64vector"
static result_t
make_u64vector_func (zzz_scm_t env, zzz_scm_t k, zzz_scm_t fill,
		    zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  int len;
  unsigned __INT64__ f;

  CHECK_TYPE (1, integer_p (k), zzz_integer_type_name);
  CHECK_RANGE (1, integer_val (k) >= 0, 
	       _("value greater than or equal to zero"));
  if (fill == zzz_undefined)
    f = 0;
  else
    {
      CHECK_TYPE (2, integer_p (fill), zzz_integer_type_name);
      f = integer_val (fill);
    }
  len = integer_val (k);
  *result = zzz_make_u64vector (len);
  while (--len >= 0)
    u64vector_val (*result)[len] = f;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector
  (u64vector num ...) => vector
  Create a homogenous unsigned 64-bit vector holding all the unsigned 64-bit
  values @var{num}s passed as arguments.
  doc:*/
#define FUNC_NAME "u64vector"
static result_t
u64vector_func (zzz_scm_t env, zzz_scm_t param, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t temp;
  zzz_scm_t res = NULL;
  int len;

  /* Param is guaranteed to be a proper list when we get here.  */
  len = zzz_list_length (param);
  res = zzz_make_u64vector (len);
  len = 0;
  temp = param;
  while (cons_p (temp))
    {
      CHECK_TYPE (len + 1, integer_p (car (temp)), zzz_integer_type_name);
      u64vector_val (res)[len] = integer_val (car (temp));
      temp = cdr (temp);
      len++;
    }
  *result = res;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector-length
  (u64vector-length vec) => integer
  Return the number of elements the homogenous unsigned 64-bit vector @var{vec}
  can hold.
  doc:*/
#define FUNC_NAME "u64vector-length"
static result_t
u64vector_length_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;

  CHECK_TYPE (1, u64vector_p (vec), zzz_u64vector_type_name);
  *result = zzz_make_integer (u64vector_len (vec));
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector-ref
  (u64vector-ref vec n) => object
  Return the unsigned 64-bit value stored at index @var{n} in the vector
  homogenous unsigned 64-bit @var{vec}.  The index @var{n} is zero-based.
  doc:*/
#define FUNC_NAME "u64vector-ref"
static result_t
u64vector_ref_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t k,
  zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned long index;

  CHECK_TYPE (1, u64vector_p (vec), zzz_u64vector_type_name);
  CHECK_TYPE (2, integer_p (k), zzz_integer_type_name);
  index = integer_val (k);
  CHECK_RANGE (2, index < u64vector_len (vec), _("valid vector index"));
  *result = zzz_make_integer ((unsigned long) u64vector_val (vec)[index]);
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector-set!
  (u64vector-set! vec n num) => *undefined*
  Store the unsigned 64-bit value at index @var{n} into the unsigned 64-bit 
  vector @var{vec}.  The index @var{n} is zero-based.
  doc:*/
#define FUNC_NAME "u64vector-set!"
static result_t
u64vector_set_x_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t k, zzz_scm_t obj,
		     zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned long index;

  CHECK_TYPE (1, u64vector_p (vec), zzz_vector_type_name);
  CHECK_TYPE (1, !ro_u64vector_p (vec), _("mutable vector"));
  CHECK_TYPE (2, integer_p (k), zzz_integer_type_name);
  CHECK_TYPE (3, integer_p (obj), zzz_integer_type_name);
  index = integer_val (k);
  CHECK_RANGE (2, index < u64vector_len (vec), _("valid vector index"));
  u64vector_val (vec)[index] = integer_val (obj);
  *result = zzz_unspecified;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector->list
  (u64vector->list vec) => list
  Return a list containing the elements of the unsigned 64-bit vector
  @var{vec}.
  doc:*/
#define FUNC_NAME "u64vector->list"
static result_t
u64vector_to_list_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t res;
  unsigned len;

  CHECK_TYPE (1, u64vector_p (vec), zzz_u64vector_type_name);
  len = u64vector_len (vec);
  res = NULL;
  while (len-- > 0)
    res = zzz_cons (zzz_make_integer 
		    ((unsigned long) u64vector_val (vec)[len]), res);
  *result = res;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  list->u64vector
  (list->u64vector list) => vector
  Return a unsigned 64-bit vector containing the elements of the list
  @var{list}.
  doc:*/
#define FUNC_NAME "list->u64vector"
static result_t
list_to_u64vector_func (zzz_scm_t env, zzz_scm_t list, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  zzz_scm_t vec = NULL;
  int len = 0;

  CHECK_TYPE (1, zzz_list_length (list) >= 0, zzz_proper_list_type_name);
  /* Param is guaranteed to be a proper list when we get here.  */
  len = zzz_list_length (list);
  vec = zzz_make_u64vector (len);
  len = 0;
  while (cons_p (list))
    {
      CHECK_TYPE (len + 1, integer_p (car (list)), zzz_integer_type_name);
      u64vector_val (vec)[len] = integer_val (car (list));
      len++;
      list = cdr (list);
    }
  *result = vec;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/*:doc
  u64vector-fill!
  (u64vector-fill! vec num) => *undefined*
  Store unsigned 64-bit value @var{num} in all elements of the unsigned 64-bit
  vector @var{vec}, overwriting the old contents of @var{vec}.
  doc:*/
#define FUNC_NAME "u64vector-fill!"
static result_t
u64vector_fill_x_func (zzz_scm_t env, zzz_scm_t vec, zzz_scm_t fill,
		    zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;
  unsigned len;

  CHECK_TYPE (1, u64vector_p (vec), zzz_u64vector_type_name);
  CHECK_TYPE (1, !ro_u64vector_p (vec), _("mutable vector"));
  CHECK_TYPE (2, integer_p (fill), zzz_integer_type_name);
  len = u64vector_len (vec);
  while (len-- > 0)
    u64vector_val (vec)[len] = integer_val (fill);
  *result = zzz_unspecified;
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

/* Constructor function for vector objects.  Expects the desired
   vector len as a long value in @var{data0}.  Returns @var{tagged}.  */
static void *
u64vector_constructor (zzz_tagged_t tagged, void * data0,
		    void * data1, void * data2)
{
  unsigned long len = (long) data0;
  unsigned __INT64__ * vec;
  unsigned long x;

  vec = zzz_malloc (sizeof (unsigned __INT64__ ) * len);
  for (x = 0; x < len; x++)
    vec[x] = 0;
  tagged->fill[1] = (zzz_object_t) vec;
  tagged->fill[2] = (zzz_object_t) len;
  return tagged;
}

static void
u64vector_print (zzz_scm_t port, zzz_tagged_t tagged, zzz_print_state_t state)
{
  zzz_scm_t result;
  unsigned __INT64__ * vec = u64vector_val (tagged);
  unsigned long len = u64vector_len (tagged);
  unsigned long x;
  char buf[64];
  int l;

  zzz_port_puts (port, "#u64(", 5, &result);
  for (x = 0; x < len; x++)
    {
      l = sprintf (buf, "%llu", vec[x]);
      zzz_port_puts (port, buf, l, &result);
      if (x < len - 1)
	zzz_port_putc (' ', port, &result);
    }
  zzz_port_putc (')', port, &result);
}

static void
u64vector_free (zzz_tagged_t tagged)
{
  zzz_free (u64vector_val (tagged),
	    sizeof (unsigned __INT64__) * u64vector_len (tagged));
}

static int
u64vector_equal (zzz_tagged_t tagged0, zzz_tagged_t tagged1)
{
  unsigned __INT64__ * vec1 = u64vector_val (tagged0);
  unsigned long len1 = u64vector_len (tagged0);
  unsigned __INT64__ * vec2 = u64vector_val (tagged1);
  unsigned long len2 = u64vector_len (tagged1);
  unsigned long x;

  if (len1 != len2)
    return 0;
  for (x = 0; x < len1; x++)
    {
      if (vec1[x] != vec2[x])
	return 0;
    }
  return 1;
}

#endif /* HAVE_LONG_LONG */

#if HAVE_LONG_LONG

zzz_scm_t
zzz_make_s64vector (int len)
{
  return zzz_create_tagged_cell (zzz_tagged_type_s64vector,
				 (void *) ((zzz_object_t) len), NULL, NULL);
}

zzz_scm_t
zzz_make_ro_s64vector (int len)
{
  return zzz_create_tagged_cell (zzz_tagged_type_s64vector | tagged_info_ro,
				 (void *) ((zzz_object_t) len), NULL, NULL);
}

zzz_scm_t
zzz_make_u64vector (int len)
{
  return zzz_create_tagged_cell (zzz_tagged_type_u64vector,
				 (void *) ((zzz_object_t) len), NULL, NULL);
}

zzz_scm_t
zzz_make_ro_u64vector (int len)
{
  return zzz_create_tagged_cell (zzz_tagged_type_u64vector | tagged_info_ro,
				 (void *) ((zzz_object_t) len), NULL, NULL);
}

#endif /* HAVE_LONG_LONG */

result_t
zzz_init_uvector64 (void)
{
#if HAVE_LONG_LONG
  zzz_tagged_type_s64vector =
    zzz_define_tagged_type (s64vector_constructor, s64vector_print,
			    s64vector_free, NULL, s64vector_equal);
  zzz_tagged_type_u64vector =
    zzz_define_tagged_type (u64vector_constructor, u64vector_print,
			    u64vector_free, NULL, u64vector_equal);

  zzz_define_function ("s64vector?", (zzz_prim_t) s64vector_p_func,
		       argv_1_0_0);
  zzz_define_function ("make-s64vector", (zzz_prim_t) make_s64vector_func,
		       argv_1_1_0);
  zzz_define_function ("s64vector-length", (zzz_prim_t) s64vector_length_func,
		       argv_1_0_0);
  zzz_define_function ("s64vector", (zzz_prim_t) s64vector_func, argv_0_0_1);
  zzz_define_function ("s64vector-ref", (zzz_prim_t) s64vector_ref_func,
		       argv_2_0_0);
  zzz_define_function ("s64vector-set!", (zzz_prim_t) s64vector_set_x_func,
		       argv_3_0_0);
  zzz_define_function ("s64vector->list", (zzz_prim_t) s64vector_to_list_func,
		       argv_1_0_0);
  zzz_define_function ("list->s64vector", (zzz_prim_t) list_to_s64vector_func,
		       argv_1_0_0);
  zzz_define_function ("s64vector-fill!", (zzz_prim_t) s64vector_fill_x_func,
		       argv_2_0_0);

  zzz_define_function ("u64vector?", (zzz_prim_t) u64vector_p_func,
		       argv_1_0_0);
  zzz_define_function ("make-u64vector", (zzz_prim_t) make_u64vector_func,
		       argv_1_1_0);
  zzz_define_function ("u64vector-length", (zzz_prim_t) u64vector_length_func,
		       argv_1_0_0);
  zzz_define_function ("u64vector", (zzz_prim_t) u64vector_func, argv_0_0_1);
  zzz_define_function ("u64vector-ref", (zzz_prim_t) u64vector_ref_func,
		       argv_2_0_0);
  zzz_define_function ("u64vector-set!", (zzz_prim_t) u64vector_set_x_func,
		       argv_3_0_0);
  zzz_define_function ("u64vector->list", (zzz_prim_t) u64vector_to_list_func,
		       argv_1_0_0);
  zzz_define_function ("list->u64vector", (zzz_prim_t) list_to_u64vector_func,
		       argv_1_0_0);
  zzz_define_function ("u64vector-fill!", (zzz_prim_t) u64vector_fill_x_func,
		       argv_2_0_0);
#endif /* HAVE_LONG_LONG */

  return RESULT_SUCCESS;
}

int zzz_config_have_uvector64 = 1;

#else /* !ENABLE_UVECTOR */

int zzz_config_have_uvector64 = 0;

#endif /* !ENABLE_UVECTOR */
