Boost logo

Boost :

Subject: Re: [boost] [local] Any "active Boost library author" in favor of Boost.Local?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-25 15:29:44


On Fri, Nov 25, 2011 at 2:42 PM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> Observe:

First of all, thanks, these examples are helping me a _lot_ :) Look
you can also turn the local function into the Phoenix function:

#include <boost/local/function.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/function.hpp>
#include <iostream>

struct x {
    void f() {
        void BOOST_LOCAL_FUNCTION_PARAMS(bind this) {
            this_->publ();
            this_->prot();
            this_->priv();
        } BOOST_LOCAL_FUNCTION_NAME(loc)
        // call it regularly:
        loc();
        // turn it into a phoenix function:
        boost::phoenix::function<decltype(loc)> phoenixf = loc;
        phoenixf()();
   }

public:
   void publ() { std::cout << "public" << std::endl; }
protected:
   void prot() { std::cout << "protected" << std::endl; }
private:
   void priv() { std::cout << "private" << std::endl; }
};

int main ( ) {
   x xx;
   xx.f();
   return 0;
}

In fact you could even trivially write a macro to directly generate
the Phoenix functor from the local scope:

struct x {
    void f() {
        void BOOST_LOCAL_FUNCTION_PARAMS(bind this) {
            this_->publ();
            this_->prot();
            this_->priv();
        } BOOST_LOCAL_FUNCTION_PHOENIX(phoenixloc)
        phoenixf()();
   }

public:
   void publ() { std::cout << "public" << std::endl; }
protected:
   void prot() { std::cout << "protected" << std::endl; }
private:
   void priv() { std::cout << "private" << std::endl; }
};

Where:

#define BOOST_LOCAL_FUNCTION_PHOENIX(name) \
    BOOST_LOCAL_FUNCTION_NAME(BOOST_PP_CAT(boost_local_phoenix, __LINE__)) \
    boost::phoenix::function<decltype(BOOST_PP_CAT(boost_local_phoenix,
__LINE__))> phoenixf = BOOST_PP_CAT(boost_local_phoenix, __LINE__);

Finally, I can trivially provide a BOOST_LOCAL_FUNCTION_TYPEOF(name)
to replace the decltype above (so it doesn't have to use C++11 at
all).

Would this be useful? Is this what you meant when you proposed to try
to use local functions to define Phoenix functions?

> #include <boost/phoenix/core.hpp>
> #include <boost/phoenix/function.hpp>
> #include <iostream>
>
> struct x {
>    void f() {
>        // call it regularly:
>        f_impl()(this);
>        // turn it into a phoenix function:
>        boost::phoenix::function<f_impl> localf = f_impl();
>        localf(this)();
>    }
>
> public:
>    void publ() { std::cout << "public" << std::endl; }
> protected:
>    void prot() { std::cout << "protected" << std::endl; }
> private:
>    void priv() { std::cout << "private" << std::endl; }
>
>    struct f_impl
>    {
>        typedef void result_type;
>        template<typename This>
>        void operator()(This this_) const
>        {
>            this_->publ();
>            this_->prot(); // error
>            this_->priv(); // error
>        }
>    };
> };
>
> int main ( ) {
>    x xx;
>    xx.f();
>    return 0;
> }

Thanks the clarifications.
--Lorenzo


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