translator は重い (memory を喰う) ので iterator をさらに抽出

汚い! きしょい! Push する引数を減らさんが為に悪夢のような cast。何かもっと賢いやりかたは無いものか…

va_arg は読む数が静的に決まってる場合にも overhead があるんだろうか。

enum _tr_msg {
[...]
};
typedef enum _tr_msg tr_msg;
/**
 * Iterators:
 *
 * Read-only iterators for vector and list.  These are supertypes of
 * the corresponding translators.  These types aren't meant to be
 * opaque; the members can be directly modified[...]
 */

/* Don't reorder the members! */
struct _list_iterator {
    ScmObj src;
    ScmObj cur;
};

/* Don't reorder the members! */
struct _vector_iterator {
    ScmObj src;
    int index;
};

struct _sequence_iterator {
    ScmObj (*trans)(sequence_iterator *i, tr_msg msg);
    union {
        list_iterator lst;
        vector_iterator vec;
    } u;
};

/* List-specific macros. */
#define ITL_INIT(_i, _in)     ((_i).u.lst.src = (_in),                  \
                               (_i).u.lst.cur = (_in),                  \
                               (_i).trans = (ScmObj(*)())listran) ←
#define ITL_GET_OBJ(_i)       (CAR((_i).u.lst.cur))
[...]

/* Vector-specific macros. */
#define ITV_INIT(_i, _in)  ((_i).u.vec.src = (_in),                     \
                            (_i).u.vec.index = 0,                       \
                            (_i).trans = (ScmObj(*)())vectran)
#define ITV_GET_OBJ(_i)    (SCM_VECTOR_VEC((_i).u.vec.src)[(_i).u.vec.index]) ←
[...]

/* Polymorphic macros. */
#define IT_CALL(_i, _msg)  ((*(_i).trans)(&(_i), (_msg)))
#define IT_GET_OBJ(_i)     (IT_CALL((_i), IT_MSG_GET_OBJ)) ←
[...]

/**
 * Translators:
 * 
 * These utilities aid in copying a sequence with modifications to
 * some parts of it.  [...]The
 * translator works as a copy-on-write iterator for lists or vectors.
 * [...]
 */

typedef struct _list_translator list_translator;
typedef struct _vector_translator vector_translator;
typedef struct _sequence_translator sequence_translator;

typedef struct _vector_iterator vector_iterator;
typedef struct _list_iterator list_iterator;
typedef struct _sequence_iterator sequence_iterator;

struct _list_translator {
    list_iterator iter;
    ScmObj output;
    ScmQueue q;
};

struct _vector_translator {
    vector_iterator iter;
    ScmObj diff;
    ScmQueue q;                 /* Points to diff. */
    int growth;
};

struct _sequence_translator {
    ScmObj (*trans)(sequence_translator *t, tr_msg msg, ScmObj obj);
    union {
        list_translator lst;
        vector_translator vec;
    } u;
};

/*
 * Operations on translators.  If a list- or vector-specific macro has
 * the same name (sans prefix) as a polymorphic one, the former tends
 * to be faster.
 */

/* List-specific macros. */
#define TRL_INIT(_t, _in)     ((_t).u.lst.output = SCM_INVALID,         \
                               SCM_QUEUE_POINT_TO((_t).u.lst.q,         \
                                                  (_t).u.lst.output),   \
                               (_t).u.lst.iter.src = (_in),             \
                               (_t).u.lst.iter.cur = (_in),             \
                               (_t).trans = listran)
#define TRL_GET_OBJ(_t)       ITL_GET_OBJ(*(sequence_iterator*)&(_t)) ←
[...]

/* Vector-specific macros. */
#define TRV_INIT(_t, _in)  ((_t).u.vec.diff = SCM_NULL,                 \
                            SCM_QUEUE_POINT_TO((_t).u.vec.q,            \
                                               (_t).u.vec.diff),        \
                            (_t).u.vec.iter.src = (_in),                \
                            (_t).u.vec.iter.index = 0,                  \
                            (_t).u.vec.growth = 0,                      \
                            (_t).trans = vectran)
#define TRV_GET_OBJ(_t)    ITV_GET_OBJ(*(sequence_iterator*)&(_t)) ←
[...]
#define TRV_EXTRACT(_t)    (TRV_CALL((_t), TR_MSG_EXTRACT, SCM_INVALID))
#define TRV_CALL(_t, _m, _p) (vectran(&(_t), (_m), (_p)))

/* Polymorphic macros. */
#define TR_CALL(_t, _msg, _p) ((*(_t).trans)(&(_t), (_msg), (_p)))
#define TR_GET_OBJ(_t)     IT_GET_OBJ(*(sequence_iterator*)&(_t)) ←
[...]
#define TR_EXTRACT(_t)     (TR_CALL((_t), TR_MSG_EXTRACT, SCM_INVALID))