Opened 10 years ago

Last modified 8 years ago

#7996 new Bugs

phoenix::bind does not protoify the bound arguments

Reported by: Andrey Semashev Owned by: Thomas Heller
Milestone: To Be Determined Component: phoenix
Version: Boost Release Branch Severity: Problem
Keywords: phoenix bind proto log Cc:

Description

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:

#include <boost/phoenix.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/value_ref.hpp>

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)
{
    if (!level || level.get() == logging::trivial::info)
        return "normal";
    logging::trivial::severity_level lvl = level.get();
    if (lvl < logging::trivial::info)
        return "low";
    else
        return "critical";
}

int main(int, char*[])
{
    logging::formatter fmt =
        expr::stream << boost::phoenix::bind(&severity_level_as_urgency, logging::trivial::severity);

    return 0;
}

The example creates a formatter function object that should call severity_level_as_urgency function to convert the severity level to string and put its result into a stream.

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 attached to the ticket.

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.

To compile the test code you will have to checkout Boost.Log from SVN:

svn co https://boost-log.svn.sourceforge.net/svnroot/boost-log/branches/bleeding-edge -r 822 boost-log

Then the relevant directories have to be linked/copied into the Boost tree.

PS: The issue came from the mailing list:

http://lists.boost.org/Archives/boost/2013/02/200701.php

Attachments (1)

build_error.txt (7.4 KB ) - added by Andrey Semashev 10 years ago.
Compilation error

Download all attachments as: .zip

Change History (11)

by Andrey Semashev, 10 years ago

Attachment: build_error.txt added

Compilation error

comment:1 by Thomas Heller, 10 years ago

Hi Andrey,

I am not sure what the problem here *exactly* is. I just checked the code of phoenix bind and all other phoenix expressions, they never use boost::proto::detail::protoify, the use the regular and document boost::proto::make_expr functionality. I am not sure who to blame here. However i think it rather is Boost.Log in this case, as phoenix uses official and document functions of proto. This means i needed to change every phoenix expression in order to work with boost.log which uses an undocument private function out of the detail namespace of a library.

That being said, this would probably need closer investigation. I will try to take a close look next week.

in reply to:  1 comment:2 by Andrey Semashev, 10 years ago

Replying to theller:

I'm by far not an expert in Boost.Proto but as far as I understand protoify is used internally by Boost.Proto to envelop objects participating in template expressions into Boost.Proto expression tree structures. In particular this is done to all terminals, and this behavior is used by Boost.Log to transparently convert all attribute_keywords to attribute_actors.

Boost.Phoenix doesn't use protoify directly, but it does so through some public interface of Boost.Proto (which is probably make_expr, I don't know for sure). My guess is that phoenix::bind doesn't treat the bound arguments the same way Boost.Phoenix treats other terminals in template expressions. This results in bound arguments not being enveloped into Boost.Proto terminal structures and consequently it doesn't invoke protoify and breaks Boost.Log.

I will be happy to use a public interface of Boost.Proto or Boost.Phoenix to achieve what I need. I just didn't find such an interface. Please, tell me if there is one.

comment:3 by Andrey Semashev, 9 years ago

Any updates about this problem?

comment:4 by John Fletcher <J.P.Fletcher@…>, 9 years ago

I am going to start to look at this problem. My first reaction is that if Thomas did not know an answer, and he wrote version 3 of phoenix to use proto, then I am going to have to do quite a lot of digging to find this one. John

in reply to:  4 comment:5 by John Fletcher <J.P.Fletcher@…>, 9 years ago

Replying to John Fletcher <J.P.Fletcher@…>:

I am going to start to look at this problem. My first reaction is that if Thomas did not know an answer, and he wrote version 3 of phoenix to use proto, then I am going to have to do quite a lot of digging to find this one. John

This is not working.

comment:6 by John Fletcher <J.P.Fletcher@…>, 9 years ago

Sorry, response on the wrong item.

in reply to:  6 comment:7 by John Fletcher <J.P.Fletcher@…>, 9 years ago

Replying to John Fletcher <J.P.Fletcher@…>:

Sorry, response on the wrong item.

It was "this is not working" which was on the wrong bug trac. I have yet to start on this one. John

comment:8 by Smithd413, 8 years ago

Component: phoenixxpressive
Milestone: To Be DeterminedWebsite 1.X
Owner: changed from Thomas Heller to Eric Niebler
Severity: ProblemNot Applicable
Type: BugsLibrary Submissions
Version: Boost Release BranchBoost.Build-M3

Thanks so much for sharing this excellent info! I'm seeking forward to see much more posts! beececefeeeeeeec

comment:9 by Andrey Semashev, 8 years ago

Component: xpressivephoenix
Milestone: Website 1.XTo Be Determined
Owner: changed from Eric Niebler to Thomas Heller
Severity: Not ApplicableProblem
Type: Library SubmissionsBugs
Version: Boost.Build-M3Boost Release Branch

comment:10 by John Fletcher <J.P.Fletcher@…>, 8 years ago

Andy My apologies I have never got around to looking at this one. John

Note: See TracTickets for help on using tickets.