|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-10 20:21:41
From: "David Abrahams" <david.abrahams_at_[hidden]>
> I understand, now. Thanks!
>
> It's not bad, but I don't yet see how to get it to deal with another
> level of iteration. Repeat 'N' of my macro typically contains a
> construct like:
>
> <class T1, class T2, ... class T(N-1)>
>
> You can't just create make1.h, make2.h,... can you?
That would require something a lot less intuitive at the point of definition,
yes. I'm just talking about the first level where you basically only have one
macro to expand.
I am (for obvious reasons) more used to my own library that does the same type
of stuff, so I'll give you an example from that. This is a generalized closure
to return from operator->* and it is intended to be used for smart_ptr types of
classes. Please note the use of at least 5 different recursive primitives. In
order to use an iterative mechanism, they entire thing would have to be
implemented much differently and a lot less straight forward. You could
eliminate the recursion altogether, but it would be a pain. :) In order to do
that, I think you would have to have a macro that expands to a filename instead
of a macro that takes a number--at least that is the incoherent jumble that is
going on in my head right now. :) Also, you would have to implement whatever
your expanding as a separate file with free-standing macros in the place of
arguments, since macros cannot expand to include directives. Anyway, enough
rambling. :) It is easy enough to take off the top level of recursion though,
and anything helps--plus you get separate lines which makes debugging *way*
easier.
// implementation of closure if you're interested
// in any case, this could be easily ported to use BOOST_PP instead
legend:
INSERT_PUNC: produces a comma (in this case) if C != 0
LIST_CLASS_T: class T1, class T2, ... class T(C)
LIST_T: T1, T2, T3, ... T(C)
LIST_PARAMS: T1 p1, T2 p2, T3 p3, ... T(C) p(C)
LIST_PARAM_IDS: p1, p2, p3, .. p(C)
ALPHA is a rogue parameter used for cv-qualified member functions.
// [closure.h]
// non-implemented
template<class> struct closure;
// implementation for pointers-to-data-members:
// the 'make' function just returns a reference
// to the data member
template<class T, class U> struct closure<U T::*> {
typedef U& return_type;
static inline U& make(T* obj, U T::* ptr) {
return obj->*ptr;
}
};
// turn *on* the preprocessor facilities...
??=include ENABLE(linearize.h)
// specialization macro for member functions:
// a specialization is created for a pointer-to-member function
// taking 0 to UPPER_BOUND parameters
// the class stores an object pointer and the pointer-to-member
// that it is constructed with and implements an operator() to actually
// call through the pointer to member.
// It also defines a 'make' function that returns a closure object.
#define MACRO(C) \
template<class R, class T INSERT_PUNC(C, COMMA) LIST_CLASS_T(C)> \
struct closure<R (T::*)(LIST_T(C)) ALPHA> { \
private: \
T* m_obj; \
typedef R (T::* ptm_t)(LIST_T(C)) ALPHA; \
ptm_t m_ptr; \
public: \
typedef closure return_type; \
inline closure(T* obj, ptm_t ptr) : m_obj(obj), m_ptr(ptr) { \
return; \
} \
inline R operator()(LIST_PARAMS(C)) const { \
return (m_obj->*m_ptr)(LIST_PARAM_IDS(C)); \
} \
static inline closure make(T* obj, ptm_t ptr) { \
return closure(obj, ptr); \
} \
};
#define LOWER_BOUND 0
#define UPPER_BOUND 50
// generate the specializations
// note: this is done 4 times, one for each
// possible cv-qualification on a member function
#define ALPHA // no cv-qualification
#include "make.h"
#undef ALPHA
#define ALPHA const
#include "make.h"
#undef ALPHA
#define ALPHA volatile
#include "make.h"
#undef ALPHA
#define ALPHA const volatile
#include "make.h"
#undef ALPHA
// turn *off* the preprocessor facilities
??=include DISABLE(linearize.h)
// make_closure (a helper function)
// this function abstracts the difference between
// a constructor (of a function closure) and the
// implementation of a data closure.
template<class T, class ptr_mem_t>
inline typename closure<ptr_mem_t>::return_type
make_closure(T* obj, ptr_mem_t ptr) {
return closure<ptr_mem_t>::make(obj, ptr);
}
// -----
This implements a simple closure to return from operator->* for smart_ptr
classes. It works for pointers-to-data-members as well as
pointers-to-member-functions (including cv-qualifications). It can be used like
this:
template<class T> class smart_ptr {
private:
T* m_ptr;
// ...
public:
// ...
template<class U>
inline typename closure<U>::return_type operator->*(U ptr) {
return make_closure(m_obj, ptr);
}
};
class X {
void f(int x, int y) { }
};
int main() {
smart_ptr<X> px = new X;
void (X::* pf)(int, int);
(px->*pf)(2, 3);
return;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk