Boost logo

Boost :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2006-11-03 16:30:29


----- Mensaje original -----
De: Peter Dimov <pdimov_at_[hidden]>
Fecha: Viernes, Noviembre 3, 2006 9:48 pm
Asunto: Re: [boost] programmatically building a bind composition?
Para: boost_at_[hidden]

> Fernando Cacciola wrote:
>
> > Besides the error, that's the general way to go? (when I can
> > only use tuple/bind of course)
>
> Defining the function object directly without going through bind,
> as suggested by Bryan Ewbank, may be easier. The pseudocode is
> trivial:
[...]

I think the following should do, but I don't have here a
powerful enough compiler (i.e. supporting boost::result_of)
to try:

#include <boost/tuple/tuple.hpp>
#include <boost/utility/result_of.hpp>

template<typename Const> struct cons_bind;

template<typename F,typename G>
struct cons_bind<boost::tuples::cons<F,G> >
{
  typedef boost::tuples::cons<F,G> cons;
  typedef cons_bind<G> next;
  
  template<typename Arg>
  struct result:boost::result_of<
    F(typename next::template result<Arg>::type)
>
  {};
  
  template<typename Arg>
  static typename result<Arg>::type
  call(const cons& c,const Arg& a)
  {
    return c.head(next::call(c.tail,a));
  }
};

template<typename F>
struct cons_bind<boost::tuples::cons<F,boost::tuples::null_type> >
{
  typedef boost::tuples::cons<F,boost::tuples::null_type> cons;

  template<typename Arg>
  struct result:boost::result_of<F(Arg)>
  {};
  
  template<typename Arg>
  static typename result<Arg>::type
  call(const cons& c,const Arg& a)
  {
    return c.head(a);
  }
};

template<typename Tuple>
struct tuple_bind
{
  tuple_bind(const Tuple& t):t(t){}
  
  typedef cons_bind<typename Tuple::inherited> helper_cons_bind;
  
  template<typename Arg>
  typename helper_cons_bind::template result<Arg>::type
  operator()(const Arg& a)
  {
    return helper_cons_bind::call(t,a);
  }
  
private:
  Tuple t;
};

// testing

#include <cmath>
#include <iostream>

int main()
{
  typedef boost::tuple<
    double (*)(double),
    double (*)(double)
> tuple_t;
  
  tuple_t t(std::sin,std::cos);
  tuple_bind<tuple_t> tb(t);
  
  std::cout<<tb(0.0)<<std::endl;
};

HTH

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk