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))