|
Boost Users : |
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-02-26 00:00:19
AMDG
Scott Meyers wrote:
> Steven Watanabe wrote:
>
>> typedef make_features<mpl::vector<int, char, double> >::type f1;
>> typedef make_features<mpl::vector<int, double> >::type f2;
>> typedef make_features<mpl::vector<char> >::type f3;
>> BOOST_MPL_ASSERT((boost::is_base_and_derived<f2, f1>));
>> BOOST_MPL_ASSERT((boost::is_base_and_derived<f3, f1>));
>>
>
> Sorry for taking so long to reply, but TMP always makes my head explode, and it
> takes a while to pick up the pieces and put them back together. In this case, I
> could have saved myself the explosion, because this interface offers behavior
> that is backwards from what I want. The conversion I want to allow is from
> fewer features to more, so I don't want f2 and f3 to be bases of f1, I want f1
> to be a base for both f2 and f3.
>
Oops. I see.
>
> What I don't know is a good way to give Features<T> the appropriate number of
> virtual base classes. Can somebody help?
>
The key thing to note is that you don't need to directly inherit
from N base classes. You can create a two argument template
and chain them together.
#include <boost/mpl/empty_base.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/remove_if.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
template<class Base1, class Base2>
struct VirtualInherit : virtual Base1, virtual Base2 {
};
template<class Sequence>
struct MakeFeatures;
using namespace boost::mpl;
typedef vector<int, char, double, void> AllFeatures;
template<class T, class U>
struct Difference : remove_if<T, contains<U, _> > {};
template<class Original, class New>
struct Insert : copy_if<AllFeatures, contains<typename
push_back<Original, New>::type, _1> > {};
template<class Original, class Added>
struct GetFeaturesBases : transform<Added, MakeFeatures<Insert<Original,
_1> > > {};
template<class FeatureList>
struct Features : virtual fold<
typename GetFeaturesBases<FeatureList, typename
Difference<AllFeatures, FeatureList>::type>::type,
empty_base,
VirtualInherit<_, _>
>::type {};
template<class Sequence>
struct MakeFeatures {
typedef Features<typename copy<Sequence, back_inserter<vector0<> >
>::type> type;
};
int main() {
typedef MakeFeatures<vector<int, char, double> >::type f1;
typedef MakeFeatures<vector<int, double> >::type f2;
typedef MakeFeatures<vector<char> >::type f3;
BOOST_MPL_ASSERT((boost::is_base_and_derived<f1, f2>));
BOOST_MPL_ASSERT((boost::is_base_and_derived<f1, f3>));
}
In Christ,
Steven Watanabe
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net