Boost logo

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