/*
 * uvector - uniform (homogeneous) numeric vector types (SRFI-4)
 *
 *  Copyright(C) 1999-2002 by Shiro Kawai (shiro@acm.org)
 *
 *  Permission to use, copy, modify, distribute this software and
 *  accompanying documentation for any purpose is hereby granted,
 *  provided that existing copyright notices are retained in all
 *  copies and that this notice is included verbatim in all
 *  distributions.
 *  This software is provided as is, without express or implied
 *  warranty.  In no circumstances the author(s) shall be liable
 *  for any damages arising out of the use of this software.
 *
 *  This file is automatically generated.  DO NOT EDIT.
 *  $Id: uvector.h.sh,v 1.21 2002/12/25 23:52:53 shirok Exp $
 */

#ifndef GAUCHE_UVECTOR_H
#define GAUCHE_UVECTOR_H

#include <gauche.h>

/*
 * This header file is for other extension modules which need
 * to access uniform vectors in C level.
 */

#if SIZEOF_LONG == 4
#ifdef WORDS_BIGENDIAN
typedef struct ScmInt64Rec {
    unsigned long hi;
    unsigned long lo;
} ScmInt64;
#else  /* !WORDS_BIGENDIAN */
typedef struct ScmInt64Rec {
    unsigned long lo;
    unsigned long hi;
} ScmInt64;
#endif /* !WORDS_BIGENDIAN */
extern ScmObj Scm_Int64Box(ScmInt64 v);
extern ScmObj Scm_Uint64Box(ScmInt64 v);
extern ScmInt64 Scm_Int64Unbox(ScmObj o, int clamp);
extern ScmInt64 Scm_Uint64Unbox(ScmObj o, int clamp);
#endif /* SIZEOF_LONG == 4 */

#if SIZEOF_INT >= 4
typedef int           SCM_UVECTOR_INT32;
typedef unsigned int  SCM_UVECTOR_UINT32;
#else
typedef long          SCM_UVECTOR_INT32;
typedef unsigned long SCM_UVECTOR_UINT32;
#endif

#if SIZEOF_LONG >= 8
typedef long          SCM_UVECTOR_INT64;
typedef unsigned long SCM_UVECTOR_UINT64;
#else
typedef ScmInt64     SCM_UVECTOR_INT64;
typedef ScmInt64     SCM_UVECTOR_UINT64;
#endif

/* Clamp flag for arithmetic operations */
enum {
    SCM_UVECTOR_CLAMP_NONE = 0,
    SCM_UVECTOR_CLAMP_LO   = 1,
    SCM_UVECTOR_CLAMP_HI   = 2,
    SCM_UVECTOR_CLAMP_BOTH = 3
};

/* Operation flag */
enum {
    SCM_UVECTOR_ADD,
    SCM_UVECTOR_SUB,
    SCM_UVECTOR_MUL,
    SCM_UVECTOR_DIV,
    SCM_UVECTOR_AND,
    SCM_UVECTOR_IOR,
    SCM_UVECTOR_XOR
};

/* Useful constants */
extern ScmObj Scm_UvectorS32Max;  /* Scheme 2^31-1 */
extern ScmObj Scm_UvectorS32Min;  /* Scheme -2^31  */
extern ScmObj Scm_UvectorU32Max;  /* Scheme 2^32-1 */
extern ScmObj Scm_UvectorU32Min;  /* Scheme 0      */
extern ScmObj Scm_UvectorS64Max;  /* Scheme 2^63-1 */
extern ScmObj Scm_UvectorS64Min;  /* Scheme -2^63  */
extern ScmObj Scm_UvectorU64Max;  /* Scheme 2^64-1 */
extern ScmObj Scm_UvectorU64Min;  /* Scheme 0      */

/*
 * Common structure for generic uvector operation
 */
typedef struct ScmUVectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    void *elements;
} ScmUVector;

SCM_CLASS_DECL(Scm_UVectorClass);
#define SCM_CLASS_UVECTOR         (&Scm_UVectorClass)
#define SCM_UVECTOR(obj)          ((ScmUVector*)(obj))
#define SCM_UVECTORP(obj)         Scm_TypeP(obj, SCM_CLASS_UVECTOR)
#define SCM_UVECTOR_SIZE(obj)     (SCM_UVECTOR(obj)->size)
#define SCM_UVECTOR_IMMUTABLE_P(obj) (SCM_UVECTOR(obj)->immutable)
#define SCM_UVECTOR_OWNER(obj)    (SCM_UVECTOR(obj)->owner)
#define SCM_UVECTOR_ELEMENTS(obj) (SCM_UVECTOR(obj)->elements)

#define SCM_UVECTOR_CHECK_MUTABLE(obj)                 \
  do { if (SCM_UVECTOR_IMMUTABLE_P(obj)) {             \
    Scm_Error("uniform vector is immutable: %S", obj); \
  }} while (0)

extern int Scm_UVectorElementSize(ScmClass *klass);
extern ScmObj Scm_MakeUVector(ScmClass *klass, int size, void *init);
extern ScmObj Scm_MakeUVectorFull(ScmClass *klass, int size, void *init,
                                  int immutablep, void *owner);

/* S8Vector */

typedef struct ScmS8VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    signed char *elements;
} ScmS8Vector;

SCM_CLASS_DECL(Scm_S8VectorClass);
#define SCM_CLASS_S8VECTOR  (&Scm_S8VectorClass)

#define SCM_S8VECTOR(obj)        ((ScmS8Vector*)(obj))
#define SCM_S8VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_S8VECTOR)
#define SCM_S8VECTOR_SIZE(obj)   (SCM_S8VECTOR(obj)->size)
#define SCM_S8VECTOR_ELEMENTS(obj) (SCM_S8VECTOR(obj)->elements)

extern ScmObj Scm_MakeS8Vector(int size, signed char fill);
extern ScmObj Scm_MakeS8VectorFromArray(int size, const signed char array[]);
extern ScmObj Scm_MakeS8VectorFromArrayShared(int size, signed char array[]);
extern ScmObj Scm_S8VectorFill(ScmS8Vector *vec, signed char fill, int, int);
extern ScmObj Scm_S8VectorRef(ScmS8Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_S8VectorSet(ScmS8Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_S8VectorToList(ScmS8Vector *vec, int start, int end);
extern ScmObj Scm_ListToS8Vector(ScmObj list, int clamp);
extern ScmObj Scm_S8VectorCopy(ScmS8Vector *vec, int start, int end);
extern ScmObj Scm_S8VectorCopyX(ScmS8Vector *dst, ScmS8Vector *src);
extern ScmObj Scm_S8VectorToVector(ScmS8Vector *vec, int start, int end);
extern ScmObj Scm_VectorToS8Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_S8VectorOp(ScmS8Vector *dest, ScmS8Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_S8VectorDotProd(ScmS8Vector *v0, ScmObj v1);
extern ScmObj Scm_S8VectorRangeCheck(ScmS8Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_S8VectorClamp(ScmS8Vector *v0, ScmObj min, ScmObj max);

/* U8Vector */

typedef struct ScmU8VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    unsigned char *elements;
} ScmU8Vector;

SCM_CLASS_DECL(Scm_U8VectorClass);
#define SCM_CLASS_U8VECTOR  (&Scm_U8VectorClass)

#define SCM_U8VECTOR(obj)        ((ScmU8Vector*)(obj))
#define SCM_U8VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_U8VECTOR)
#define SCM_U8VECTOR_SIZE(obj)   (SCM_U8VECTOR(obj)->size)
#define SCM_U8VECTOR_ELEMENTS(obj) (SCM_U8VECTOR(obj)->elements)

extern ScmObj Scm_MakeU8Vector(int size, unsigned char fill);
extern ScmObj Scm_MakeU8VectorFromArray(int size, const unsigned char array[]);
extern ScmObj Scm_MakeU8VectorFromArrayShared(int size, unsigned char array[]);
extern ScmObj Scm_U8VectorFill(ScmU8Vector *vec, unsigned char fill, int, int);
extern ScmObj Scm_U8VectorRef(ScmU8Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_U8VectorSet(ScmU8Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_U8VectorToList(ScmU8Vector *vec, int start, int end);
extern ScmObj Scm_ListToU8Vector(ScmObj list, int clamp);
extern ScmObj Scm_U8VectorCopy(ScmU8Vector *vec, int start, int end);
extern ScmObj Scm_U8VectorCopyX(ScmU8Vector *dst, ScmU8Vector *src);
extern ScmObj Scm_U8VectorToVector(ScmU8Vector *vec, int start, int end);
extern ScmObj Scm_VectorToU8Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_U8VectorOp(ScmU8Vector *dest, ScmU8Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_U8VectorDotProd(ScmU8Vector *v0, ScmObj v1);
extern ScmObj Scm_U8VectorRangeCheck(ScmU8Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_U8VectorClamp(ScmU8Vector *v0, ScmObj min, ScmObj max);

/* S16Vector */

typedef struct ScmS16VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    signed short *elements;
} ScmS16Vector;

SCM_CLASS_DECL(Scm_S16VectorClass);
#define SCM_CLASS_S16VECTOR  (&Scm_S16VectorClass)

#define SCM_S16VECTOR(obj)        ((ScmS16Vector*)(obj))
#define SCM_S16VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_S16VECTOR)
#define SCM_S16VECTOR_SIZE(obj)   (SCM_S16VECTOR(obj)->size)
#define SCM_S16VECTOR_ELEMENTS(obj) (SCM_S16VECTOR(obj)->elements)

extern ScmObj Scm_MakeS16Vector(int size, signed short fill);
extern ScmObj Scm_MakeS16VectorFromArray(int size, const signed short array[]);
extern ScmObj Scm_MakeS16VectorFromArrayShared(int size, signed short array[]);
extern ScmObj Scm_S16VectorFill(ScmS16Vector *vec, signed short fill, int, int);
extern ScmObj Scm_S16VectorRef(ScmS16Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_S16VectorSet(ScmS16Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_S16VectorToList(ScmS16Vector *vec, int start, int end);
extern ScmObj Scm_ListToS16Vector(ScmObj list, int clamp);
extern ScmObj Scm_S16VectorCopy(ScmS16Vector *vec, int start, int end);
extern ScmObj Scm_S16VectorCopyX(ScmS16Vector *dst, ScmS16Vector *src);
extern ScmObj Scm_S16VectorToVector(ScmS16Vector *vec, int start, int end);
extern ScmObj Scm_VectorToS16Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_S16VectorOp(ScmS16Vector *dest, ScmS16Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_S16VectorDotProd(ScmS16Vector *v0, ScmObj v1);
extern ScmObj Scm_S16VectorRangeCheck(ScmS16Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_S16VectorClamp(ScmS16Vector *v0, ScmObj min, ScmObj max);

/* U16Vector */

typedef struct ScmU16VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    unsigned short *elements;
} ScmU16Vector;

SCM_CLASS_DECL(Scm_U16VectorClass);
#define SCM_CLASS_U16VECTOR  (&Scm_U16VectorClass)

#define SCM_U16VECTOR(obj)        ((ScmU16Vector*)(obj))
#define SCM_U16VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_U16VECTOR)
#define SCM_U16VECTOR_SIZE(obj)   (SCM_U16VECTOR(obj)->size)
#define SCM_U16VECTOR_ELEMENTS(obj) (SCM_U16VECTOR(obj)->elements)

extern ScmObj Scm_MakeU16Vector(int size, unsigned short fill);
extern ScmObj Scm_MakeU16VectorFromArray(int size, const unsigned short array[]);
extern ScmObj Scm_MakeU16VectorFromArrayShared(int size, unsigned short array[]);
extern ScmObj Scm_U16VectorFill(ScmU16Vector *vec, unsigned short fill, int, int);
extern ScmObj Scm_U16VectorRef(ScmU16Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_U16VectorSet(ScmU16Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_U16VectorToList(ScmU16Vector *vec, int start, int end);
extern ScmObj Scm_ListToU16Vector(ScmObj list, int clamp);
extern ScmObj Scm_U16VectorCopy(ScmU16Vector *vec, int start, int end);
extern ScmObj Scm_U16VectorCopyX(ScmU16Vector *dst, ScmU16Vector *src);
extern ScmObj Scm_U16VectorToVector(ScmU16Vector *vec, int start, int end);
extern ScmObj Scm_VectorToU16Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_U16VectorOp(ScmU16Vector *dest, ScmU16Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_U16VectorDotProd(ScmU16Vector *v0, ScmObj v1);
extern ScmObj Scm_U16VectorRangeCheck(ScmU16Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_U16VectorClamp(ScmU16Vector *v0, ScmObj min, ScmObj max);

/* S32Vector */

typedef struct ScmS32VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    SCM_UVECTOR_INT32 *elements;
} ScmS32Vector;

SCM_CLASS_DECL(Scm_S32VectorClass);
#define SCM_CLASS_S32VECTOR  (&Scm_S32VectorClass)

#define SCM_S32VECTOR(obj)        ((ScmS32Vector*)(obj))
#define SCM_S32VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_S32VECTOR)
#define SCM_S32VECTOR_SIZE(obj)   (SCM_S32VECTOR(obj)->size)
#define SCM_S32VECTOR_ELEMENTS(obj) (SCM_S32VECTOR(obj)->elements)

extern ScmObj Scm_MakeS32Vector(int size, SCM_UVECTOR_INT32 fill);
extern ScmObj Scm_MakeS32VectorFromArray(int size, const SCM_UVECTOR_INT32 array[]);
extern ScmObj Scm_MakeS32VectorFromArrayShared(int size, SCM_UVECTOR_INT32 array[]);
extern ScmObj Scm_S32VectorFill(ScmS32Vector *vec, SCM_UVECTOR_INT32 fill, int, int);
extern ScmObj Scm_S32VectorRef(ScmS32Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_S32VectorSet(ScmS32Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_S32VectorToList(ScmS32Vector *vec, int start, int end);
extern ScmObj Scm_ListToS32Vector(ScmObj list, int clamp);
extern ScmObj Scm_S32VectorCopy(ScmS32Vector *vec, int start, int end);
extern ScmObj Scm_S32VectorCopyX(ScmS32Vector *dst, ScmS32Vector *src);
extern ScmObj Scm_S32VectorToVector(ScmS32Vector *vec, int start, int end);
extern ScmObj Scm_VectorToS32Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_S32VectorOp(ScmS32Vector *dest, ScmS32Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_S32VectorDotProd(ScmS32Vector *v0, ScmObj v1);
extern ScmObj Scm_S32VectorRangeCheck(ScmS32Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_S32VectorClamp(ScmS32Vector *v0, ScmObj min, ScmObj max);

/* U32Vector */

typedef struct ScmU32VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    SCM_UVECTOR_UINT32 *elements;
} ScmU32Vector;

SCM_CLASS_DECL(Scm_U32VectorClass);
#define SCM_CLASS_U32VECTOR  (&Scm_U32VectorClass)

#define SCM_U32VECTOR(obj)        ((ScmU32Vector*)(obj))
#define SCM_U32VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_U32VECTOR)
#define SCM_U32VECTOR_SIZE(obj)   (SCM_U32VECTOR(obj)->size)
#define SCM_U32VECTOR_ELEMENTS(obj) (SCM_U32VECTOR(obj)->elements)

extern ScmObj Scm_MakeU32Vector(int size, SCM_UVECTOR_UINT32 fill);
extern ScmObj Scm_MakeU32VectorFromArray(int size, const SCM_UVECTOR_UINT32 array[]);
extern ScmObj Scm_MakeU32VectorFromArrayShared(int size, SCM_UVECTOR_UINT32 array[]);
extern ScmObj Scm_U32VectorFill(ScmU32Vector *vec, SCM_UVECTOR_UINT32 fill, int, int);
extern ScmObj Scm_U32VectorRef(ScmU32Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_U32VectorSet(ScmU32Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_U32VectorToList(ScmU32Vector *vec, int start, int end);
extern ScmObj Scm_ListToU32Vector(ScmObj list, int clamp);
extern ScmObj Scm_U32VectorCopy(ScmU32Vector *vec, int start, int end);
extern ScmObj Scm_U32VectorCopyX(ScmU32Vector *dst, ScmU32Vector *src);
extern ScmObj Scm_U32VectorToVector(ScmU32Vector *vec, int start, int end);
extern ScmObj Scm_VectorToU32Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_U32VectorOp(ScmU32Vector *dest, ScmU32Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_U32VectorDotProd(ScmU32Vector *v0, ScmObj v1);
extern ScmObj Scm_U32VectorRangeCheck(ScmU32Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_U32VectorClamp(ScmU32Vector *v0, ScmObj min, ScmObj max);

/* S64Vector */

typedef struct ScmS64VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    SCM_UVECTOR_INT64 *elements;
} ScmS64Vector;

SCM_CLASS_DECL(Scm_S64VectorClass);
#define SCM_CLASS_S64VECTOR  (&Scm_S64VectorClass)

#define SCM_S64VECTOR(obj)        ((ScmS64Vector*)(obj))
#define SCM_S64VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_S64VECTOR)
#define SCM_S64VECTOR_SIZE(obj)   (SCM_S64VECTOR(obj)->size)
#define SCM_S64VECTOR_ELEMENTS(obj) (SCM_S64VECTOR(obj)->elements)

extern ScmObj Scm_MakeS64Vector(int size, SCM_UVECTOR_INT64 fill);
extern ScmObj Scm_MakeS64VectorFromArray(int size, const SCM_UVECTOR_INT64 array[]);
extern ScmObj Scm_MakeS64VectorFromArrayShared(int size, SCM_UVECTOR_INT64 array[]);
extern ScmObj Scm_S64VectorFill(ScmS64Vector *vec, SCM_UVECTOR_INT64 fill, int, int);
extern ScmObj Scm_S64VectorRef(ScmS64Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_S64VectorSet(ScmS64Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_S64VectorToList(ScmS64Vector *vec, int start, int end);
extern ScmObj Scm_ListToS64Vector(ScmObj list, int clamp);
extern ScmObj Scm_S64VectorCopy(ScmS64Vector *vec, int start, int end);
extern ScmObj Scm_S64VectorCopyX(ScmS64Vector *dst, ScmS64Vector *src);
extern ScmObj Scm_S64VectorToVector(ScmS64Vector *vec, int start, int end);
extern ScmObj Scm_VectorToS64Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_S64VectorOp(ScmS64Vector *dest, ScmS64Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_S64VectorDotProd(ScmS64Vector *v0, ScmObj v1);
extern ScmObj Scm_S64VectorRangeCheck(ScmS64Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_S64VectorClamp(ScmS64Vector *v0, ScmObj min, ScmObj max);

/* U64Vector */

typedef struct ScmU64VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    SCM_UVECTOR_UINT64 *elements;
} ScmU64Vector;

SCM_CLASS_DECL(Scm_U64VectorClass);
#define SCM_CLASS_U64VECTOR  (&Scm_U64VectorClass)

#define SCM_U64VECTOR(obj)        ((ScmU64Vector*)(obj))
#define SCM_U64VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_U64VECTOR)
#define SCM_U64VECTOR_SIZE(obj)   (SCM_U64VECTOR(obj)->size)
#define SCM_U64VECTOR_ELEMENTS(obj) (SCM_U64VECTOR(obj)->elements)

extern ScmObj Scm_MakeU64Vector(int size, SCM_UVECTOR_UINT64 fill);
extern ScmObj Scm_MakeU64VectorFromArray(int size, const SCM_UVECTOR_UINT64 array[]);
extern ScmObj Scm_MakeU64VectorFromArrayShared(int size, SCM_UVECTOR_UINT64 array[]);
extern ScmObj Scm_U64VectorFill(ScmU64Vector *vec, SCM_UVECTOR_UINT64 fill, int, int);
extern ScmObj Scm_U64VectorRef(ScmU64Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_U64VectorSet(ScmU64Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_U64VectorToList(ScmU64Vector *vec, int start, int end);
extern ScmObj Scm_ListToU64Vector(ScmObj list, int clamp);
extern ScmObj Scm_U64VectorCopy(ScmU64Vector *vec, int start, int end);
extern ScmObj Scm_U64VectorCopyX(ScmU64Vector *dst, ScmU64Vector *src);
extern ScmObj Scm_U64VectorToVector(ScmU64Vector *vec, int start, int end);
extern ScmObj Scm_VectorToU64Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_U64VectorOp(ScmU64Vector *dest, ScmU64Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_U64VectorDotProd(ScmU64Vector *v0, ScmObj v1);
extern ScmObj Scm_U64VectorRangeCheck(ScmU64Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_U64VectorClamp(ScmU64Vector *v0, ScmObj min, ScmObj max);

/* F32Vector */

typedef struct ScmF32VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    float *elements;
} ScmF32Vector;

SCM_CLASS_DECL(Scm_F32VectorClass);
#define SCM_CLASS_F32VECTOR  (&Scm_F32VectorClass)

#define SCM_F32VECTOR(obj)        ((ScmF32Vector*)(obj))
#define SCM_F32VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_F32VECTOR)
#define SCM_F32VECTOR_SIZE(obj)   (SCM_F32VECTOR(obj)->size)
#define SCM_F32VECTOR_ELEMENTS(obj) (SCM_F32VECTOR(obj)->elements)

extern ScmObj Scm_MakeF32Vector(int size, float fill);
extern ScmObj Scm_MakeF32VectorFromArray(int size, const float array[]);
extern ScmObj Scm_MakeF32VectorFromArrayShared(int size, float array[]);
extern ScmObj Scm_F32VectorFill(ScmF32Vector *vec, float fill, int, int);
extern ScmObj Scm_F32VectorRef(ScmF32Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_F32VectorSet(ScmF32Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_F32VectorToList(ScmF32Vector *vec, int start, int end);
extern ScmObj Scm_ListToF32Vector(ScmObj list, int clamp);
extern ScmObj Scm_F32VectorCopy(ScmF32Vector *vec, int start, int end);
extern ScmObj Scm_F32VectorCopyX(ScmF32Vector *dst, ScmF32Vector *src);
extern ScmObj Scm_F32VectorToVector(ScmF32Vector *vec, int start, int end);
extern ScmObj Scm_VectorToF32Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_F32VectorOp(ScmF32Vector *dest, ScmF32Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_F32VectorDotProd(ScmF32Vector *v0, ScmObj v1);
extern ScmObj Scm_F32VectorRangeCheck(ScmF32Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_F32VectorClamp(ScmF32Vector *v0, ScmObj min, ScmObj max);

/* F64Vector */

typedef struct ScmF64VectorRec {
    SCM_HEADER;
    unsigned int immutable : 1;
    int size : (SIZEOF_INT*CHAR_BIT-1);
    void *owner;
    double *elements;
} ScmF64Vector;

SCM_CLASS_DECL(Scm_F64VectorClass);
#define SCM_CLASS_F64VECTOR  (&Scm_F64VectorClass)

#define SCM_F64VECTOR(obj)        ((ScmF64Vector*)(obj))
#define SCM_F64VECTORP(obj)       SCM_XTYPEP(obj, SCM_CLASS_F64VECTOR)
#define SCM_F64VECTOR_SIZE(obj)   (SCM_F64VECTOR(obj)->size)
#define SCM_F64VECTOR_ELEMENTS(obj) (SCM_F64VECTOR(obj)->elements)

extern ScmObj Scm_MakeF64Vector(int size, double fill);
extern ScmObj Scm_MakeF64VectorFromArray(int size, const double array[]);
extern ScmObj Scm_MakeF64VectorFromArrayShared(int size, double array[]);
extern ScmObj Scm_F64VectorFill(ScmF64Vector *vec, double fill, int, int);
extern ScmObj Scm_F64VectorRef(ScmF64Vector *vec, int index, ScmObj fallback);
extern ScmObj Scm_F64VectorSet(ScmF64Vector *vec, int index, ScmObj val, int clamp);
extern ScmObj Scm_F64VectorToList(ScmF64Vector *vec, int start, int end);
extern ScmObj Scm_ListToF64Vector(ScmObj list, int clamp);
extern ScmObj Scm_F64VectorCopy(ScmF64Vector *vec, int start, int end);
extern ScmObj Scm_F64VectorCopyX(ScmF64Vector *dst, ScmF64Vector *src);
extern ScmObj Scm_F64VectorToVector(ScmF64Vector *vec, int start, int end);
extern ScmObj Scm_VectorToF64Vector(ScmVector *vec, int start, int end, int clamp);

/* arithmetics */
extern ScmObj Scm_F64VectorOp(ScmF64Vector *dest, ScmF64Vector *v0, ScmObj v1, int op, int clamp);
extern ScmObj Scm_F64VectorDotProd(ScmF64Vector *v0, ScmObj v1);
extern ScmObj Scm_F64VectorRangeCheck(ScmF64Vector *v0, ScmObj min, ScmObj max);
extern ScmObj Scm_F64VectorClamp(ScmF64Vector *v0, ScmObj min, ScmObj max);

#endif /* GAUCHE_UVECTOR_H */
