
On 2/6/13 3:17 PM, Andrey Semashev wrote:
On Sat, Feb 2, 2013 at 8:26 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Hi,
I have a problem with Boost.Phoenix v3 bind implementation when used with attribute keywords from Boost.Log. For some reason phoenix::bind does not apply proto::detail::protoify to the bound arguments which breaks compilation of some formatting expressions in Boost.Log.
Here's an example:
namespace logging = boost::log; namespace expr = boost::log::expressions; namespace phoenix = boost::phoenix;
// Custom severity level formatting function std::string severity_level_as_urgency( logging::value_ref< logging::trivial::severity_level, logging::trivial::tag::severity > const& level);
// The function initializes the logging library void init_logging() { // ... sink->set_formatter ( expr::stream << phoenix::bind(&severity_level_as_urgency, logging::trivial::severity) ); }
The intended behavior of this code is to invoke severity_level_as_urgency function with severity level value extracted from a log record and put the result of this function into a stream, thus forming a formatted representation of the record.
trivial::severity is a keyword of type expr::attribute_keyword< ... >. Keywords themselves should never actually be embedded into phoenix expressions, instead I have attribute_actor that implements all the necessary work to extract attribute values. I have specialized proto::detail::protoify template for attribute_keyword (including references and reference_wrappers thereof) so that it is automatically converted to attribute_actor whenever it participates in expressions. But it doesn't work with the above code, Boost.Phoenix embeds attribute_keyword as is into the expression. This results in the error I posted in the end of the post.
I realize that proto::detail::protoify is not for public use and may not be intended for my use case but I did not find any other way to implement what I described. Anyway, I think bind should treat bound arguments as child subexpressions and protoify them. Is that right?
In case if you want to see the complete code of the example and/or Boost.Log, you can check it out from SVN:
svn co https://boost-log.svn.sourceforge.net/svnroot/boost- log/branches/bleeding-edge boost-log
The example resides in libs/log/example/doc/extension_app_launcher.cpp. I have modified it to call or_none() on trivial::severity so that the example compiles; in order to reproduce the problem you have to remove this call (it sould be performed by my protoify specialization instead).
Ping? Anyone? Should I create a ticket for Boost.Phoenix?
That would be best, yes. Seems Thomas Heller is very busy these days. I'll see if I can take over some of the support tasks. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com