XSetWindowAttributes_ xswa = {So here is how you do it. Note that this is a sketch of an implementation rather than a full implementation, but it should suffice as a proof of viability of the concept. (Though not of its sanity. If you want that, see the previous post's equivalence.)
bit_gravity_ = ForgetGravity,
background_pixmap_ = None
};
For reference,
XSetWindowAttributes
is defined here.
// If this line doesn't work -- it's untested -- it may be necessary
// to extract the type via template deduction instead.
#define MEMBER_TYPEOF(x) BOOST_TYPEOF((NULL)->*(x))
struct background_pixmap_tag {
typedef MEMBER_TYPEOF(XSetWindowAttributes::background_pixmap) type;
static type XSetWindowAttributes::* const mptr =
XSetWindowAttributes::background_pixmap;
static void apply(XSetWindowAttributes &str, char const *buf)
{ str.*mptr = *(type const *)buf; }
};
struct background_pixel_tag {
typedef MEMBER_TYPEOF(XSetWindowAttributes::background_pixel) type;
static type XSetWindowAttributes::* const mptr =
XSetWindowAttributes::background_pixel;
static void apply(XSetWindowAttributes &str, char const *buf)
{ str.*mptr = *(type const *)buf; }
};
// ... and so forth; these tag-types are boring and can be generated by,
// e.g., a macro taking the type name and a Boost.PP Sequence of member names.
// (And save that sequence; you'll want it for other things.)
// Compute the maximum size of the raw data types of each member of the
// underlying struct; this is left as an exercise for the reader. Hint:
// generate a boost::mpl::vector of tag-types from the Boost.PP.Sequence
// of member names.
static const size_t max_data_size = boost::mpl:: ... ;
struct ParameterSetter {
apply_fptr_t apply_fun;
char buffer[max_data_size];
}
template <typename Tag>
struct Parameter {
ParameterSetter operator=(typename Tag::type value) {
inline ParameterSetter ps = { &Tag::apply };
(typename Tag::type *)(void *)(char *)(ps.buffer) = value;
return ps;
}
};
Parameterbackground_pixmap_;
Parameterbackground_pixel_;
// ... more preprocessor-handlable declarations ...
struct XSetWindowAttributes_ {
ParameterSetter a0;
ParameterSetter a1;
// ... the maximum N needed is the sequence size == member count ...
ParameterSetter aN;
XSetWindowAttributes attr;
inline operator XSetWindowAttributes &() {
if (a0.apply_fun) (a0.apply_fun)(attr, a0.buffer) else return attr;
if (a1.apply_fun) (a1.apply_fun)(attr, a1.buffer) else return attr;
// ... you know the drill by now ...
if (aN.apply_fun) (aN.apply_fun)(attr, aN.buffer) else return attr;
return attr;
}
inline XSetWindowAttributes* operator &()
{ return &(this->operator XSetWindowAttributes &()); }
};
// ... and Bob's your uncle.
XSetWindowAttributes_ xswa = {
bit_gravity_ = ForgetGravity,
background_pixmap_ = None
};
(Explanations next time.)
No comments:
Post a Comment