|
Boost : |
From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2001-12-14 12:03:19
Mat Marcus wrote:
> Aleksey> MSVC does compile this one :). I've uploaded the example
> Aleksey> file (derived_class_gen.cpp) to the MPL directory in the
> Aleksey> files section, if it's of any interest.
>
> MSVC 6 and 7b2 still refuse to compile this for me. Perhaps its
> because I'm using the 9/19 MPL?
MSVC 6.5 indeed rejected it, and after I've found a workaround, the
situation became exactly the opposite - the new code was compiling under VC
6.5, but rejected by 7.0b2. Working with a pair of MS compilers is even more
fun than with just one :). Anyway, I ifdef'ed the code that caused troubles,
and also uploaded a minor revision of the library that works with the latest
PREPROCESSOR library to the Files section
(http://groups.yahoo.com/group/boost/files/mpl/mpl-dec-01-01.zip, haven't
got time to check it in into CVS yet), so now everything should work.
> Also, I suggest that we add some
> author attribution to derived_class_gen.cpp.
Ouch, I thought I did it. Fixed.
> In particular, the Loki
> copyright notice should probably appear.
Done, but note that the code I posted as an example of "how I would write an
equivalent of Loki's GenScatterHierarchy using MPL" is _not_ derived from
the code in Andrei's book. It's a simplified version of "structure
generator" class template my colleague and I wrote some time ago here at
work; the class is basically used to generate a family of ordinary C++
structs (or "property classes", or "named tuples", depending on how you look
at them :) that can be freely assigned to each other basing on the
"compatibility" of their content, e.g.
DEFINE_STRUCTURE_GEN_MEMBER(name);
DEFINE_STRUCTURE_GEN_MEMBER(last_name);
DEFINE_STRUCTURE_GEN_MEMBER(street);
DEFINE_STRUCTURE_GEN_MEMBER(city);
DEFINE_STRUCTURE_GEN_MEMBER(zip_code);
// struct my_person
// {
// std::string m_name;
// std::string m_street;
// std::string m_city;
// int m_zip_code;
// };
typedef structure_gen< boost::mpl::type_list<
name<std::string>
, street<std::string>
, city<std::string>
, zip_code<int>
> >::type my_person;
// struct her_person
// {
// std::string m_name;
// int m_zip_code;
// };
typedef structure_gen< boost::mpl::type_list<
name<std::string>
, zip_code<int>
> >::type her_person;
int main()
{
my_person p1;
her_person p2;
p1.m_name = "Helena";
p1.m_zip_code = 10001;
p2 = p1; // ok
assert(p2.m_name == p1.m_name);
assert(p2.m_zip_code == p1.m_zip_code);
// p1 = p2; // error
}
where definitions of 'structure_gen' and DEFINE_STRUCTURE_GEN_MEMBER macro
are:
namespace aux {
// Dave Abrahams' technique: factoring out 'struct_t'
// definition from 'struct_t_gen' (below) clears up the
// generated type "signature"
template<typename BaseStruct, typename T>
struct struct_t : BaseStruct, T
{
struct_t() {}
template<typename U> struct_t(U const& other)
: BaseStruct(other)
, T(static_cast<T const&>(other))
{
}
template<typename U> struct_t& operator=(U const& other)
{
BaseStruct::operator=(other);
T::operator=(static_cast<T const&>(other));
return *this;
}
};
struct struct_t_gen
{
template<typename BaseStruct, typename T>
struct apply
{
// another Dave's technique: 'select_type' is used to avoid
// a need to have/inherit from a dummy base class
typedef typename boost::mpl::select_type<
boost::is_same<BaseStruct, boost::mpl::null_t>::value
, T
, struct_t<BaseStruct, T>
>::type type;
};
};
} // namespace aux
template<typename Memebers>
struct structure_gen
{
typedef typename boost::mpl::accumulate<
Memebers
, boost::mpl::null_t
, aux::struct_t_gen
>::type type;
};
#define DEFINE_STRUCTURE_GEN_MEMBER(name) \
template<typename T> \
struct name \
{ \
typedef T value_type; \
name(T x = T()) : m_##name(x) {} \
T m_##name; \
} \
/**/
> Mat> * MPL needs documentation now. I believe some mpl naming
> Mat> conventions could be improved as well.
>
> Aleksey> Do you have any specific suggestions in mind (besides
> Aleksey> 'for_each' :)?
>
> The other idea is that the MAKE_F_XXX macros could be more suggestive
> once the right name for "function classes" is found.
I think the current names are ok, but I am always open to better
suggestions.
Aleksey
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk