Boost logo

Boost :

Subject: Re: [boost] [log][phoenix] Questions on porting to phoenix
From: Joel de Guzman (joel_at_[hidden])
Date: 2012-01-24 19:20:02


On 1/24/2012 2:41 PM, Andrey Semashev wrote:
> As I understand, the only way I can do that, except for reimplementing
> phoenix::actor, is to derive my actor from phoenix::actor. This makes
> the attribute keyword non-POD in C++03 but is it still safe to be
> constructed in the namespace scope, provided that the keyword does not
> have its own data members? Also, what should be the template argument
> for the phoenix::actor specialization? Here's the code example to
> illustrate what I'm talking about:
>
> template< typename DescriptorT >
> struct attribute_keyword :
> public phoenix::actor< what_should_be_here? >
> {
> // extracts the attribute value
> template< typename ContextT >
> DescriptorT::value_type operator() (ContextT const& ctx) const;
>
> // adds a default value
> attribute_keyword_with_default< DescriptorT >
> or_default(DescriptorT::value_type) const;
> };
>
> // assume there are specializations of custom_terminal and
> // is_custom_terminal for attribute_keyword
>
> // This is generated by BOOST_LOG_REGISTER_ATTRIBUTE
> namespace tag {
> struct severity
> {
> typedef my_severity value_type;
> typedef attribute_name name_type;
>
> // returns an equivalent for "Severity"
> // I want to cache its result in the AST
> static name_type get_name();
> };
> }
> const attribute_keyword< tag::severity > severity; // is this safe?

This has been pretty much the practice in phoenix (and even in spirit)
for placeholders and such. We don't recommend this now for several reasons.
One big reason is that the proliferation of such namespace scope proto
objects (there's a lot in spirit), even if PODs, slow down compile time
considerably (esp. on g++ as reported by Joel Falcou et.al) (note:
apparently, only proto objects are affected by this).

Now, what I advocate is exposing the typedef:

  attribute_keyword< tag::severity > severity_type;

and letting the user create a local (function scope) object himself:

  boost::log::severity_type severity;

The typing involved is the same. With namespace scope objects, the
"best-practice" is for you to put these objects in a spacial
namespace and hoist it into the client namespace using using
declarations anyway (e.g.):

  using boost::log::severity;

The compile time problem is very significant that in Spirit and indeed
in Phoenix-3, we have special PP defines to disable the predefined
objects (e.g.):

  #define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS

Regards,

-- 
Joel de Guzman
http://www.boostpro.com
http://boost-spirit.com

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