|
Boost Users : |
From: David Abrahams (dave_at_[hidden])
Date: 2007-03-23 10:47:28
on Fri Mar 23 2007, Scott Meyers <usenet-AT-aristeia.com> wrote:
> David Abrahams wrote:
>> Nothing; this is clearly a bug in MPL
>
> As a workaround, I thought I'd write an erase_first function as shown
> below, but this seems to have the same problem. Perhaps this is because
> I'm using erase in my implementation, and erase_key may, I suppose, be
> implemented on top of erase.
It is *extremely* likely that erase_key and erase produce the same
result.
> More likely, I'm doing something wrong.
Not all that likely.
> More likely still, the way I'm doing it is gross.
Well yeah. The un-gross way is to wait for Aleksey to fix it. He's
unfortunately in a work crunch at the moment, but I'd guess he could
address it within a couple of days.
> I'd appreciate
> feedback on the implementation of my erase_first function, where I've
> put comments showing the procedural equivalent of what I'm trying to do
> in each statement.
>
> Also, does anybody have a workaround for the bug in erase_key?
It's highly unlikely that any opportunity for such a workaround exists
in the set code.
> Thanks,
>
> Scott
>
> #include <boost/mpl/set.hpp>
> #include <boost/mpl/equal.hpp>
> #include <boost/mpl/erase.hpp>
> #include <boost/mpl/if.hpp>
> #include <boost/mpl/end.hpp>
> #include <boost/mpl/find.hpp>
>
> namespace mpl = boost::mpl;
> using mpl::_1;
> using mpl::_2;
>
> struct A {};
> struct B {};
>
> typedef mpl::set<A, B> set1;
> typedef mpl::set<B, A> set2;
>
>
> // return Seq with the first occurrance of T removed
> template<typename Seq, typename T>
> struct erase_first {
> // i = Seq.find(T)
> typedef typename mpl::find<Seq, T>::type i;
>
> // found = (i == Seq.end()) ? false : true
> typedef typename mpl::if_<
> typename boost::is_same<i,
> typename mpl::end<Seq>::type
> >::type,
> mpl::false_,
> mpl::true_
> >::type found;
mpl::if_< pred, mpl::false_, mpl::true_>::type
is usually better written
mpl::not_<pred>
> // type = found ? Seq : Seq.erase(i)
> typedef typename mpl::if_<found,
> Seq,
> typename mpl::erase<Seq, i>::type
> >::type type;
> };
>From scratch (untested):
template <class Seq, class E>
struct erase_first
{
typedef typename mpl::find<Seq, T>::type i;
typedef typename eval_if<
boost::is_same<i, typename mpl::end<Seq> >
, mpl::identity<Seq>
, mpl::erase<Seq,i>
>::type type;
};
HTH,
-- Dave Abrahams Boost Consulting www.boost-consulting.com
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