mirror of
https://github.com/NixOS/nix.git
synced 2025-11-15 15:02:42 +01:00
Improve C++ code generation for terms.
This commit is contained in:
parent
02a4ea0617
commit
61198a89a1
1 changed files with 86 additions and 33 deletions
|
|
@ -170,70 +170,123 @@ namespace term
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// a few shortcuts to keep things clear.
|
||||||
|
|
||||||
# define TRM_NIL
|
# define TRM_NIL
|
||||||
# define TRM_NIL_ARGS(...)
|
# define TRM_NIL_ARGS(...)
|
||||||
|
# define TRM_EMPTY_ARRAY (0, ())
|
||||||
|
|
||||||
# define TRM_ARRAY_DATA(Array) BOOST_PP_ARRAY_DATA(Array)
|
# define TRM_SEQ_HEAD BOOST_PP_SEQ_HEAD
|
||||||
# define TRM_ARRAY_SIZE(Array) BOOST_PP_ARRAY_SIZE(Array)
|
# define TRM_SEQ_TAIL BOOST_PP_SEQ_TAIL
|
||||||
|
|
||||||
|
# define TRM_ARRAY_DATA BOOST_PP_ARRAY_DATA
|
||||||
|
# define TRM_ARRAY_SIZE BOOST_PP_ARRAY_SIZE
|
||||||
|
# define TRM_ARRAY_ELEM BOOST_PP_ARRAY_ELEM
|
||||||
|
# define TRM_SEQ_TO_ARRAY BOOST_PP_SEQ_TO_ARRAY
|
||||||
|
# define TRM_ARRAY_TO_SEQ(Array) \
|
||||||
|
BOOST_PP_TUPLE_TO_SEQ(TRM_ARRAY_SIZE(Array), TRM_ARRAY_DATA(Array))
|
||||||
|
|
||||||
|
// TRM_EVAL macros are used to do the convertion of array to sequence and to
|
||||||
|
// provide a default case when the array cannot be converted into a
|
||||||
|
// sequence. This case happens when you need to convert a zero size array.
|
||||||
|
|
||||||
# define TRM_EVAL_0(Macro1, Macro2, Array, Default) Default
|
# define TRM_EVAL_0(Macro1, Macro2, Array, Default) Default
|
||||||
/*
|
# define TRM_EVAL_1(Macro1, Macro2, Array, Default) \
|
||||||
define TRM_EVAL_1(Macro1, Macro2, Array, Default) \
|
Macro1(Macro2, TRM_ARRAY_TO_SEQ(Array))
|
||||||
Macro1(Macro2, BOOST_PP_TUPLE_TO_SEQ(TRM_ARRAY_SIZE(Array), TRM_ARRAY_DATA(Array)))
|
|
||||||
*/
|
|
||||||
# define TRM_EVAL_2 TRM_EVAL_1
|
# define TRM_EVAL_2 TRM_EVAL_1
|
||||||
# define TRM_EVAL_3 TRM_EVAL_1
|
# define TRM_EVAL_3 TRM_EVAL_1
|
||||||
# define TRM_EVAL_4 TRM_EVAL_1
|
# define TRM_EVAL_4 TRM_EVAL_1
|
||||||
|
|
||||||
# define TRM_EVAL_II(eval) eval
|
# define TRM_EVAL_II(eval) eval
|
||||||
# define TRM_EVAL_I(n, tuple) TRM_EVAL_ ## n
|
# define TRM_EVAL_I(n, _) TRM_EVAL_ ## n
|
||||||
# define TRM_EVAL(Macro1, Macro2, Array, Default) \
|
# define TRM_EVAL(Macro1, Macro2, Array, Default) \
|
||||||
TRM_EVAL_II(TRM_EVAL_I Array (Macro1, Macro2, Array, Default))
|
TRM_EVAL_II(TRM_EVAL_I Array (Macro1, Macro2, Array, Default))
|
||||||
|
|
||||||
|
# define TRM_DEFAULT1(D0) D0
|
||||||
|
|
||||||
|
// Default TRM_<fun> are taking an array and return a sequence. To keep the
|
||||||
|
// same type, you need to specify which type you expect to have. The reason
|
||||||
|
// is that array support to have no values where sequence do not support it.
|
||||||
|
// On the contrary, all operations are well defined on sequences but none
|
||||||
|
// are defined on arrays.
|
||||||
|
|
||||||
# define TRM_MAP_HELPER(R, Macro, Elt) (Macro(Elt))
|
# define TRM_MAP_HELPER(R, Macro, Elt) (Macro(Elt))
|
||||||
# define TRM_MAP_(Macro, Seq) \
|
# define TRM_MAP_(Macro, Seq) \
|
||||||
BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq)
|
BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq)
|
||||||
# define TRM_MAP_SEQ(Macro, Seq) \
|
# define TRM_MAP_SEQ(Macro, Seq) \
|
||||||
TRM_MAP_(Macro, Seq)
|
TRM_MAP_(Macro, Seq)
|
||||||
# define TRM_MAP_SEQ_TO_ARRAY(Macro, Seq) \
|
# define TRM_MAP_ARRAY_(Macro, Seq) \
|
||||||
BOOST_PP_SEQ_TO_ARRAY(TRM_MAP_SEQ(Macro, Seq))
|
TRM_SEQ_TO_ARRAY(TRM_MAP_SEQ(Macro, Seq))
|
||||||
# define TRM_MAP_ARRAY(Macro, Array) \
|
# define TRM_MAP_ARRAY(Macro, Array) \
|
||||||
TRM_EVAL(TRM_MAP_SEQ_TO_ARRAY, Macro, Array, (0, ()))
|
TRM_EVAL(TRM_MAP_ARRAY_, Macro, Array, \
|
||||||
# define TRM_MAP(Macro, Array) \
|
TRM_DEFAULT1(TRM_EMPTY_ARRAY) \
|
||||||
TRM_EVAL(TRM_MAP_SEQ, Macro, Array, TRM_NIL)
|
)
|
||||||
|
# define TRM_MAP(Macro, Array) \
|
||||||
|
TRM_EVAL(TRM_MAP_SEQ, Macro, Array, \
|
||||||
|
TRM_DEFAULT1(TRM_NIL) \
|
||||||
|
)
|
||||||
|
|
||||||
|
// Apply a macro on all elements (array / sequence)
|
||||||
|
|
||||||
# define TRM_APPLY_HELPER(R, Macro, Elt) Macro(Elt)
|
# define TRM_APPLY_HELPER(R, Macro, Elt) Macro(Elt)
|
||||||
# define TRM_APPLY_(Macro, Seq) \
|
# define TRM_APPLY_(Macro, Seq) \
|
||||||
BOOST_PP_SEQ_FOR_EACH(TRM_MAP_HELPER, Macro, Seq)
|
BOOST_PP_SEQ_FOR_EACH(TRM_APPLY_HELPER, Macro, Seq)
|
||||||
# define TRM_APPLY_SEQ(Macro, Seq) \
|
# define TRM_APPLY_SEQ(Macro, Seq) \
|
||||||
TRM_APPLY_(Macro, Seq)
|
TRM_APPLY_(Macro, Seq)
|
||||||
# define TRM_APPLY(Macro, Array) \
|
# define TRM_APPLY(Macro, Array) \
|
||||||
TRM_EVAL(TRM_APPLY_, Macro, Array, TRM_NIL)
|
TRM_EVAL(TRM_APPLY_, Macro, Array, \
|
||||||
|
TRM_DEFAULT1(TRM_NIL) \
|
||||||
|
)
|
||||||
|
|
||||||
# define TRM_HEAD(Seq) BOOST_PP_SEQ_HEAD(Seq)
|
// Apply a macro on all elements (array / sequence) and separate them by a
|
||||||
# define TRM_TAIL(Seq) BOOST_PP_SEQ_TAIL(Seq)
|
// comma.
|
||||||
|
|
||||||
# define TRM_SEPARATE_COMMA_HELPER(Elt) , Elt
|
# define TRM_SEPARATE_COMMA_HELPER(Elt) , Elt
|
||||||
# define TRM_SEPARATE_COMMA_(_, Seq) \
|
# define TRM_SEPARATE_COMMA_(_, Seq) \
|
||||||
TRM_HEAD(Seq) TRM_APPLY_SEQ(TRM_SEPARATE_COMMA_HELPER, TRM_TAIL(Seq))
|
TRM_SEQ_HEAD(Seq)
|
||||||
|
TRM_APPLY_SEQ(TRM_SEPARATE_COMMA_HELPER, TRM_SEQ_TAIL(Seq))
|
||||||
# define TRM_SEPARATE_COMMA_SEQ(Seq) \
|
# define TRM_SEPARATE_COMMA_SEQ(Seq) \
|
||||||
TRM_SEPARATE_COMMA_(dummy, Seq)
|
TRM_SEPARATE_COMMA(TRM_SEQ_TO_ARRAY(Seq))
|
||||||
# define TRM_SEPARATE_COMMA(Array) \
|
# define TRM_SEPARATE_COMMA(Array) \
|
||||||
TRM_EVAL(TRM_SEPARATE_COMMA_, dummy, Array, TRM_NIL)
|
TRM_EVAL(TRM_SEPARATE_COMMA_, dummy, Array, \
|
||||||
|
TRM_DEFAULT1(TRM_NIL) \
|
||||||
|
)
|
||||||
|
|
||||||
|
// These macro are used to define how to manipulate each argument. If the
|
||||||
|
// argument should be given by reference or by copy. You should use
|
||||||
|
// references when the element goes over a specific size and if you accept
|
||||||
|
// to see it living on the stack. You should use copies when the element is
|
||||||
|
// small and if you prefer to have it inside a register.
|
||||||
|
|
||||||
# define TRM_TYPE_REF(Type, Name) const Type&, Type &, Name
|
# define TRM_TYPE_REF(Type, Name) (const Type&, Type &, Name)
|
||||||
# define TRM_TYPE_COPY(Type, Name) const Type, Type &, Name
|
# define TRM_TYPE_COPY(Type, Name) (const Type, Type &, Name)
|
||||||
# define TRM_TYPE_TERM(Type, Name) TRM_TYPE_COPY(A ## Type, Name)
|
# define TRM_TYPE_TERM(Type, Name) TRM_TYPE_COPY(A ## Type, Name)
|
||||||
|
|
||||||
# define TRM_CONST_ABSTRACT_COPY_DECL(Copy, Ref, Name) Copy Name;
|
// Handle the different usage of the variables. Arguments are suffixed with
|
||||||
# define TRM_CONST_ABSTRACT_COPY_ARG(Copy, Ref, Name) Copy Name ## _
|
// a '_' and attributes are not.
|
||||||
# define TRM_ABSTRACT_REF_ARG(Copy, Ref, Name) Ref Name ## _
|
|
||||||
# define TRM_INIT_ATTRIBUTES(Copy, Ref, Name) Name (Name ## _)
|
# define TRM_CONST_ABSTRACT_COPY_DECL_(Copy, Ref, Name) Copy Name;
|
||||||
# define TRM_ARGUMENTS(Copy, Ref, Name) Name ## _
|
# define TRM_CONST_ABSTRACT_COPY_ARG_(Copy, Ref, Name) Copy Name ## _
|
||||||
# define TRM_COPY_IN_ARG(Copy, Ref, Name) Name ## _ = Name;
|
# define TRM_ABSTRACT_REF_ARG_(Copy, Ref, Name) Ref Name ## _
|
||||||
# define TRM_LESS_RHS_OR(Copy, Ref, Name) Name < rhs. Name ||
|
# define TRM_INIT_ATTRIBUTES_(Copy, Ref, Name) Name (Name ## _)
|
||||||
|
# define TRM_ARGUMENTS_(Copy, Ref, Name) Name ## _
|
||||||
|
# define TRM_COPY_IN_ARG_(Copy, Ref, Name) Name ## _ = Name;
|
||||||
|
# define TRM_LESS_RHS_OR_(Copy, Ref, Name) Name < rhs. Name ||
|
||||||
|
|
||||||
|
// These macro are shortcuts used to remove extra parenthesies added by
|
||||||
|
// TRM_TYPE_* macros. Without such parenthesies TRM_APPLY_HELPER won't be
|
||||||
|
// able to give the argument to these macros and arrays won't be well
|
||||||
|
// formed.
|
||||||
|
|
||||||
|
# define TRM_CONST_ABSTRACT_COPY_DECL(Elt) TRM_CONST_ABSTRACT_COPY_DECL_ Elt
|
||||||
|
# define TRM_CONST_ABSTRACT_COPY_ARG(Elt) TRM_CONST_ABSTRACT_COPY_ARG_ Elt
|
||||||
|
# define TRM_ABSTRACT_REF_ARG(Elt) TRM_ABSTRACT_REF_ARG_ Elt
|
||||||
|
# define TRM_INIT_ATTRIBUTES(Elt) TRM_INIT_ATTRIBUTES_ Elt
|
||||||
|
# define TRM_ARGUMENTS(Elt) TRM_ARGUMENTS_ Elt
|
||||||
|
# define TRM_COPY_IN_ARG(Elt) TRM_COPY_IN_ARG_ Elt
|
||||||
|
# define TRM_LESS_RHS_OR(Elt) TRM_LESS_RHS_OR_ Elt
|
||||||
|
|
||||||
|
|
||||||
// Add the implementation class as a friend class to provide access to the
|
// Add the implementation class as a friend class to provide access to the
|
||||||
// private constructor. This reduce interaction with the implementation of
|
// private constructor. This reduce interaction with the implementation of
|
||||||
|
|
@ -301,7 +354,7 @@ namespace term
|
||||||
this_type* ptr; \
|
this_type* ptr; \
|
||||||
if (ptr = dynamic_cast<this_type*>(t.ptr_)) \
|
if (ptr = dynamic_cast<this_type*>(t.ptr_)) \
|
||||||
{ \
|
{ \
|
||||||
TRM_MAP(TRM_COPY_IN_ARG, Attributes); \
|
TRM_APPLY(TRM_COPY_IN_ARG, Attributes); \
|
||||||
return parent::match ## Base ( \
|
return parent::match ## Base ( \
|
||||||
TRM_SEPARATE_COMMA_SEQ( \
|
TRM_SEPARATE_COMMA_SEQ( \
|
||||||
( t ) \
|
( t ) \
|
||||||
|
|
@ -321,7 +374,7 @@ namespace term
|
||||||
inline \
|
inline \
|
||||||
bool operator <(const Name& rhs) \
|
bool operator <(const Name& rhs) \
|
||||||
{ \
|
{ \
|
||||||
return TRM_MAP(TRM_LESS_RHS_OR, Attributes) \
|
return TRM_APPLY(TRM_LESS_RHS_OR, Attributes) \
|
||||||
parent::operator < (rhs); \
|
parent::operator < (rhs); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,7 +382,7 @@ namespace term
|
||||||
// Declare all the attributes of the current class.
|
// Declare all the attributes of the current class.
|
||||||
# define TRM_ATTRIBUTE_DECLS(Name, Base, Attributes, BaseArgs) \
|
# define TRM_ATTRIBUTE_DECLS(Name, Base, Attributes, BaseArgs) \
|
||||||
public: \
|
public: \
|
||||||
TRM_MAP(TRM_CONST_ABSTRACT_COPY_DECL, Attributes)
|
TRM_APPLY(TRM_CONST_ABSTRACT_COPY_DECL, Attributes)
|
||||||
|
|
||||||
|
|
||||||
// A class which provide static method (no virtual) to access the
|
// A class which provide static method (no virtual) to access the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue