Boost C++ Libraries: Ticket #7730: Generic specializations of is_nullary for custom terminals are not possible https://svn.boost.org/trac10/ticket/7730 <p> The is_nullary trait is specialized for all custom_terminal&lt;T&gt; to be true (see phoenix/code/is_nullary.hpp). </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;T&gt; &gt; : mpl::true_ {}; </pre><p> This is not true with regard to multiple terminals I define in Boost.Log. This forces me to specialize is_nullary for all my custom terminals, and I cannot provide a single blanket specialization for all my terminals. </p> <p> The is_nullary trait has a second template parameter which is intended to be used exactly for this purpose. A nested tag void typedef can be used to match the trait for a set of types. I could create the following specialization: </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;T&gt;, typename T::_is_my_terminal &gt; : mpl::false_ {}; </pre><p> However this extension mechanism does not work because the two specializations are considered equally specialized and the compiler reports ambiguity. </p> <p> I suggest to limit the first specialization to only match the default custom terminals, e.g.: </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;T&gt;, typename custom_terminal&lt;T&gt;::_is_default_custom_terminal &gt; : mpl::true_ {}; </pre><p> Where typedef void _is_default_custom_terminal will be added to the generic custom_terminal template. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7730 Trac 1.4.3 John Fletcher <J.P.Fletcher@…> Tue, 04 Feb 2014 00:06:52 GMT <link>https://svn.boost.org/trac10/ticket/7730#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:1</guid> <description> <p> I have implemented your test and am putting it onto develop. </p> <p> I have set it up so that for the moment it is necessary to do this before the header to use this. </p> <pre class="wiki">#define BOOST_PHOENIX_SPECIALIZE_CUSTOM_TERMINAL </pre><p> There is a test bug7730 which will test the header with the define. </p> <p> Please let me know if this works for your case. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Tue, 04 Feb 2014 00:10:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:2</guid> <description> <p> Replying to <a class="new ticket" href="https://svn.boost.org/trac10/ticket/7730" title="#7730: Bugs: Generic specializations of is_nullary for custom terminals are not possible (new)">andysem</a>: </p> <blockquote class="citation"> <p> The is_nullary trait has a second template parameter which is intended to be used exactly for this purpose. A nested tag void typedef can be used to match the trait for a set of types. I could create the following specialization: </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;T&gt;, typename T::_is_my_terminal &gt; : mpl::false_ {}; </pre></blockquote> <p> Note: I have not implemented this part of your example because as I read it this part will go into your client code. Is that correct? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Tue, 04 Feb 2014 02:42:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:1" title="Comment 1">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> I have implemented your test and am putting it onto develop. </p> <p> I have set it up so that for the moment it is necessary to do this before the header to use this. </p> <pre class="wiki">#define BOOST_PHOENIX_SPECIALIZE_CUSTOM_TERMINAL </pre><p> There is a test bug7730 which will test the header with the define. </p> <p> Please let me know if this works for your case. </p> </blockquote> <p> Since this bug affects Boost.Log (a library), I cannot define the macro in my code, so it doesn't really help me. In order to work, this has to be the default (and the only) behavior of Boost.Phoenix. To my understanding, it should be safe enough to enable it by default the way I described in the ticket, although, of course, I may be missing something. </p> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:2" title="Comment 2">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> Note: I have not implemented this part of your example because as I read it this part will go into your client code. Is that correct? </p> </blockquote> <p> Yes. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Tue, 04 Feb 2014 07:10:19 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:4</guid> <description> <p> O.K. I will leave it on test today to make sure that it is O.K. with other compilers. If all is well I will move it to the default operation then. I will notify that here. </p> <p> You may realise that I have only recently taken on the maintenance of phoenix and I don't want to break things by moving too fast. I want to get some good patches and then move them from develop to master in time for the next release of boost. </p> <p> I am concerned that there are a number of implications for the log library from problems in boost. Please let me know what the problems are and whether some of the fixes I have done have helped. Also what the most urgent things are to be fixed next. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Tue, 04 Feb 2014 07:35:13 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:4" title="Comment 4">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> O.K. I will leave it on test today to make sure that it is O.K. with other compilers. If all is well I will move it to the default operation then. I will notify that here. </p> <p> You may realise that I have only recently taken on the maintenance of phoenix and I don't want to break things by moving too fast. I want to get some good patches and then move them from develop to master in time for the next release of boost. </p> </blockquote> <p> Ok, no worries. It's not a fatal issue since the specializations for Boost.Log-specific terminals do their job of covering this problem. I appreciate your effort of taking care of Boost.Phoenix, thanks a lot for that. </p> <blockquote class="citation"> <p> I am concerned that there are a number of implications for the log library from problems in boost. Please let me know what the problems are and whether some of the fixes I have done have helped. Also what the most urgent things are to be fixed next. </p> </blockquote> <p> I think I've created tickets as I discovered problems or was told by Boost.Log users. You can find them by filtering those reported by me. I think the most critical ones right now are <a class="new ticket" href="https://svn.boost.org/trac10/ticket/7996" title="#7996: Bugs: phoenix::bind does not protoify the bound arguments (new)">#7996</a> and <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9363" title="#9363: Bugs: Reference forwarding in phoenix::bind does not work in C++11 (closed: fixed)">#9363</a>. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Tue, 04 Feb 2014 21:27:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:6</guid> <description> <p> I tried switching the patch in this to be default on and it breaks other headers unfortunately. I need to investigate further. John </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Tue, 04 Feb 2014 23:25:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:7</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:6" title="Comment 6">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> I tried switching the patch in this to be default on and it breaks other headers unfortunately. I need to investigate further. John </p> </blockquote> <p> This is not working. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Thu, 06 Feb 2014 23:52:46 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:8</guid> <description> <p> I have now sorted out the problems and committed a proposed solution to develop. Test bug7730 tests turning it off by defining BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL. John </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Fri, 21 Feb 2014 07:49:15 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:9</guid> <description> <p> WARNING - this fix may break client code which uses the boost phoenix custom_terminal. </p> <p> The solution may well be to insert the following into any overload of the struct boost::phoenix::custom_terminal: </p> <p> #ifndef BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL </p> <blockquote> <p> typedef void _is_default_custom_terminal; <em> fix for <a class="new ticket" href="https://svn.boost.org/trac10/ticket/7730" title="#7730: Bugs: Generic specializations of is_nullary for custom terminals are not possible (new)">#7730</a> </em></p> </blockquote> <p> #endif </p> <p> John </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Fri, 21 Feb 2014 09:40:18 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:10</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:9" title="Comment 9">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> WARNING - this fix may break client code which uses the boost phoenix custom_terminal. </p> <p> The solution may well be to insert the following into any overload of the struct boost::phoenix::custom_terminal: </p> <p> John </p> </blockquote> <p> The code should be in a box: </p> <pre class="wiki">#ifndef BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL typedef void _is_default_custom_terminal; // fix for #7730 #endif </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 22 Feb 2014 06:51:43 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:11</guid> <description> <p> Can this typedef be added to the default custom_terminal somehow? I suspect breaking the client's code this way won't be received well. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 09:15:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:12</guid> <description> <p> The typedef is provided in the default custom_terminal - see the code below from </p> <pre class="wiki">boost/phoenix/core/terminal.hpp </pre><pre class="wiki"> template &lt;typename T, typename Dummy&gt; struct custom_terminal #ifndef BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL { typedef void _is_default_custom_terminal; // fix for #7730 } #endif ; </pre><p> The problem arises when people developing their own terminal specialize the custom terminal. The case which was made in this bug report was for them to have the freedom I have now given. It has needed a fix in the case of Boost Spirit. I have now included a check on the spirit headers in the testing of phoenix, to pick up anything similar before it even gets into develop. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 09:47:46 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:13</guid> <description> <p> I believe I have provided a solution to this problem and also provided the user with a way to have the previous behaviour by defining BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL. </p> <p> I am now being criticised for defining such things. </p> <blockquote class="citation"> <p> This kind of switches make it difficult to use together different libraries which themselves use phoenix, unless the macro is dragged and honored to every piece of code defining a custom terminal. </p> </blockquote> <p> I don't believe that is true. You don't need to use it unless you need the old behaviour. Because all the tests for it are negative it does not have to be defined at all. </p> <p> I want to resolve this and close this bug as soon as I can. John </p> <p> I thought that was a good thing to do but could remove it and force the new behaviour. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 22 Feb 2014 10:58:13 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:14</guid> <description> <p> There is another problem with Boost.Log, see <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9693" title="#9693: Bugs: error C2039: 'proto_tag' : is not a member of ... (closed: fixed)">#9693</a>. I'm not sure what is the best course of action with that problem as I don't quite understand what is the problem there. My original suggestion in this ticket implied that the existing code would not break after this change, but I'll understand if something needs to be done in Boost.Log. My main concern though is that this can affect other Boost users (i.e. outside Boost). Is that intentional and can it be avoided (without the config macro, I mean)? </p> <p> Don't get me wrong, I'm not criticizing you, and I want this change work eventually. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 11:15:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:15 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:15</guid> <description> <p> Andy </p> <p> The only code which will break with this change, as far as I can see, is code which has a specialization of the custom terminal. I have just fixed that for Boost Spirit. The only change needed was to add the typedef. I don't think there are going to be many of those around, but I have modified the entry in <a class="missing wiki">ChangeLog</a> to be clearer. </p> <p> I intend to make the documentation clear as I get into that side of things. </p> <p> I have come to the conclusion that the client specialization does not need to use the BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL as the extra typedef is all there is. I intend to check that out, as I understand the reluctance of maintainers of other libraries to have such things in their code. </p> <p> I will look into <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9693" title="#9693: Bugs: error C2039: 'proto_tag' : is not a member of ... (closed: fixed)">#9693</a> when I get a chance. I have decided to port the proto tool display_expr inot phoenix to have a diagnostic tool. I have the basics working but need to do more on the tags to get sensible output. When I have that I will be able to dig into phoenix better. John </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 22 Feb 2014 11:26:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:16 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:16</guid> <description> <p> Nevermind the <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9693" title="#9693: Bugs: error C2039: 'proto_tag' : is not a member of ... (closed: fixed)">#9693</a>, I found out that I forgot to specialize is_nullary for my terminal. I wonder how it worked before. </p> <p> Regarding the macro. I kind of agree with the quote you presented in comment 13 because now in Boost.Log I apparently have to support both configurations. I.e. the old code with multiple is_nullary specialization don't disappear but potentially is made conditional, which is worse. Can this macro be removed and the new code be always in action? </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 11:45:02 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:17 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:17</guid> <description> <p> I have just attempted to reply and it has been rejected as spam. Would you please email me outside this system? John (J.P.Fletcher@…) </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 12:15:56 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:18 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:18</guid> <description> <p> What is needed (I think) is to provide a default value for the second template parameter. At the moment the default is void, so could we catch that? Seems risky to me. John </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 22 Feb 2014 13:13:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:19 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:19</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:18" title="Comment 18">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> What is needed (I think) is to provide a default value for the second template parameter. At the moment the default is void, so could we catch that? Seems risky to me. John </p> </blockquote> <p> Not sure what you mean, but I don't think the actual type matters. That parameter just allows to use SFINAE to eliminate specializations instead of the standard template specialization mechanism. Void is just something neutral and convenient enough. </p> <p> You could probably create some other mechanism to detect the default custom_terminal specialization. But that would still require some kind of type introspection, I think, and would arguably be slower in compile time. </p> <p> What I was suggesting is not change the approach with the _is_default_custom_terminal typedef, but just make it unconditional. You fixed Boost.Spirit already and as you said the problem is unlikely to appear outside Boost. So just document the needed change for those few who encounters the problem. </p> </description> <category>Ticket</category> </item> <item> <author>John Fletcher <J.P.Fletcher@…></author> <pubDate>Sat, 22 Feb 2014 13:49:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:20 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:20</guid> <description> <p> That is the default behaviour at the moment, so you would have to put typedefs in the ones you define. Is that sufficient or do you need more? If it is, all I need to do is to get rid of the conditional code. John </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 22 Feb 2014 14:22:53 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:21 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:21</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:20" title="Comment 20">John Fletcher &lt;J.P.Fletcher@…&gt;</a>: </p> <blockquote class="citation"> <p> That is the default behaviour at the moment, so you would have to put typedefs in the ones you define. Is that sufficient or do you need more? </p> </blockquote> <p> Yes, it is sufficient. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Thomas Heller</dc:creator> <pubDate>Tue, 11 Mar 2014 23:03:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:22 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:22</guid> <description> <p> I don't see why such a fix is necessary. Wouldn't this work? </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;even_more_custom&lt;T&gt; &gt; : ... </pre><p> This wouldn't break any exisiting code. </p> <p> FWIW, The dummy parameter only has the side effect of being able to be used with SFINAE. The main intention was to get rid of some uneeded template instatiations. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Wed, 12 Mar 2014 06:51:51 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7730#comment:23 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7730#comment:23</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/7730#comment:22" title="Comment 22">theller</a>: </p> <blockquote class="citation"> <p> I don't see why such a fix is necessary. Wouldn't this work? </p> <pre class="wiki">template &lt;typename T&gt; struct is_nullary&lt;custom_terminal&lt;even_more_custom&lt;T&gt; &gt; : ... </pre><p> This wouldn't break any exisiting code. </p> </blockquote> <p> This is what I have to do currently. The problem is that I have many such even_more_custom terminals and I have to specialize is_nullary for each and every one of them. </p> <blockquote class="citation"> <p> FWIW, The dummy parameter only has the side effect of being able to be used with SFINAE. The main intention was to get rid of some uneeded template instatiations. </p> </blockquote> <p> You can't use the parameter for SFINAE now because of the generic specialization I pointed out in the ticket description. </p> </description> <category>Ticket</category> </item> </channel> </rss>