|
Boost Users : |
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-03-18 09:55:09
Scott Meyers wrote:
> It will take me a few days to digest your comments
Hopefully not because they're confusing :-). I tried to increase
conciseness with my second post.
> (this is largely new
> territory for me), but I wanted to acknowledge your help now. Thanks
> very much.
Thanks too -- a reader who's new to the territory is most valuable to
improve one's communication skills.
>> The problem comes down to that MPL can't know where one placeholder
>> expression starts and where another one ends (denoted by uppercase
>> identifiers, above):
>
> Yes, I ran into this problem playing around as a result of the help
> posted earlier. As I said, it will take me a while to get a grasp on
> what you've done. I have to look a lot of stuff up and write a lot of
> test cases :-)
There's a slightly altered approach to this problem attached to this
message for some additional fun.
Regards,
Tobias
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/assert.hpp>
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
using boost::is_same;
// contains_if
template<typename Seq, typename Pred>
struct contains_if
: mpl::not_< boost::is_same<typename mpl::find_if<Seq,Pred>::type,
typename mpl::end<Seq>::type> >
{ };
// test it
typedef mpl::vector<int> v1;
BOOST_MPL_ASSERT(( contains_if<v1,is_same<_,int> > ));
BOOST_MPL_ASSERT_NOT(( contains_if<v1,is_same<_,char> > ));
// contains implemented on top of it
//
// other than mpl::contains this version takes a binary predicate to parametrize
// comparison
template<typename S, typename T, typename Compare = boost::is_same<_1,_2> >
struct contains
// uses 'lambda', because 'bind' requires a Metafunction Class instead of an
// arbitrary Lambda Expressions
: contains_if< S, mpl::bind<typename mpl::lambda<Compare>::type,T,_1> >
{ };
// test it
BOOST_MPL_ASSERT(( ::contains<v1,int> ));
BOOST_MPL_ASSERT_NOT(( ::contains<v1,char> ));
// a facility that allows to sustain the evaluation of placeholder expressions
template<typename PlaceholderExpr>
struct defer
{
template<typename IgnoredPlaceholder> struct get
{
typedef PlaceholderExpr type;
};
// return a dummy placeholder expression that evaluates to the
// original one (without substitution applied)
typedef typename defer<PlaceholderExpr>::template get<_> type;
};
// test it
BOOST_MPL_ASSERT(( is_same<mpl::apply< defer<_1>::type ,int>::type, _1> ));
BOOST_MPL_ASSERT(( is_same<mpl::apply<mpl::apply< defer<_1>::type,
int>::type,int>::type, int> ));
// now implement includes on top of
template<typename SuperSeq, typename SubSeq,
typename Pred = boost::is_same<_1,_2> >
struct includes
: mpl::not_< contains_if< SubSeq, mpl::not_< contains<SuperSeq,_1,
typename defer<Pred>::type > > > >
{ };
// test it
typedef mpl::vector<int> v1;
typedef mpl::vector<int,char> v2;
BOOST_MPL_ASSERT(( includes<v2, v1> ));
BOOST_MPL_ASSERT_NOT(( includes<v1, v2> ));
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