[proto] _value doesn't enforce zero arity

I see some funny behavior when misusing _value: #include <boost/proto/proto.hpp> namespace bp = boost::proto; int main(int, char**) { bp::terminal<int>::type t = {0}; bp::terminal<int>::type hmm = bp::value(t * 2); bp::terminal<int>::type uhm = bp::_value()(t * 2); bp::terminal<const int&>::type hrm = bp::value(2 * t); bp::terminal<const int&>::type feh = bp::_value()(2 * t); } Which does compile.. but the docs say that _value requires an expression of zero arity. Here as usual is an attempt at a patch, to see if I'm learning anything: BOOST_MPL_ASSERT_RELATION( remove_reference<Expr>::type::proto_arity_c, ==, 0L); in the body of struct _value in transform/args.hpp. How'd I do? -t

troy d. straszheim wrote:
troy d. straszheim wrote:
BOOST_MPL_ASSERT_RELATION( remove_reference<Expr>::type::proto_arity_c, ==, 0L);
Whoops, sorry. That doesn't work, and I'm replying to myself. Need sleep.
aaugh. I was compiling the wrong file. It does work. I'm going to bed. -t

troy d. straszheim wrote:
I see some funny behavior when misusing _value:
#include <boost/proto/proto.hpp>
namespace bp = boost::proto;
int main(int, char**) { bp::terminal<int>::type t = {0};
bp::terminal<int>::type hmm = bp::value(t * 2); bp::terminal<int>::type uhm = bp::_value()(t * 2);
bp::terminal<const int&>::type hrm = bp::value(2 * t); bp::terminal<const int&>::type feh = bp::_value()(2 * t); }
Which does compile.. but the docs say that _value requires an expression of zero arity. <snip>
Yep, it compiles, and yep, it violates the preconditions. I choose not to enforce the preconditions because doing so would cause extra template instantiations and lengthen compile times. As long as valid programs compile and do the right thing, I'm happy. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
troy d. straszheim wrote:
I see some funny behavior when misusing _value:
[snip]
Which does compile.. but the docs say that _value requires an expression of zero arity.
Yep, it compiles, and yep, it violates the preconditions. I choose not to enforce the preconditions because doing so would cause extra template instantiations and lengthen compile times. As long as valid programs compile and do the right thing, I'm happy.
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally? Best Regards, Gevorg

Gevorg Voskanyan wrote:
Eric Niebler wrote:
Yep, it compiles, and yep, it violates the preconditions. I choose not to enforce the preconditions because doing so would cause extra template instantiations and lengthen compile times. As long as valid programs compile and do the right thing, I'm happy.
OK, thanks Eric.
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS. -t

troy d. straszheim wrote:
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have
Gevorg Voskanyan wrote: those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS.
-t
That seems like a valid addition for boost.mpl to me, but in this case I was more thinking of something having effect on boost.proto only, in the spirit of e.g. BOOST_MULTI_INDEX_ENABLE_SAFE_MODE, whereas using BOOST_MPL_DISABLE_ASSERTS would probably have a broader impact. Also I think Eric would want not to have expensive checks enabled by default, so BOOST_MPL_DISABLE_ASSERTS will not be very useful for this case even if/when it is added, IMHO. Best Regards, Gevorg

on Tue Apr 07 2009, "troy d. straszheim" <troy-AT-resophonic.com> wrote:
Gevorg Voskanyan wrote:
Eric Niebler wrote:
Yep, it compiles, and yep, it violates the preconditions. I choose not to enforce the preconditions because doing so would cause extra template instantiations and lengthen compile times. As long as valid programs compile and do the right thing, I'm happy.
OK, thanks Eric.
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS.
It's a very good idea, IMO. Open a ticket? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Tue Apr 07 2009, "troy d. straszheim" <troy-AT-resophonic.com> wrote:
Gevorg Voskanyan wrote:
Eric Niebler wrote:
Yep, it compiles, and yep, it violates the preconditions. I choose not to enforce the preconditions because doing so would cause extra template instantiations and lengthen compile times. As long as valid programs compile and do the right thing, I'm happy. OK, thanks Eric.
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS.
It's a very good idea, IMO. Open a ticket?

"David Abrahams" <dave@boostpro.com> wrote in message news:m28wmbf91i.fsf@boostpro.com...
on Tue Apr 07 2009, "troy d. straszheim" <troy-AT-resophonic.com> wrote:
Gevorg Voskanyan wrote:
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS.
It's a very good idea, IMO. Open a ticket?
This flag sounds the same as the BOOST_COMPILE_TIME_DEBUG flag proposed by Eric Niebler here: http://lists.boost.org/boost-users/2009/01/44451.php. Joel de Guzman suggested making it an integer (0 == no CT debug, 1..3 CT debug levels) here: http://lists.boost.org/boostusers/2009/01/44452.php. My thought is to have one of the integer debug levels enable compile-time tracing of "interesting" template instantiations using Steven Watanabe's template_profiler. For this to work, the library author would have to mark the "interesting" template classes and functions with "PROFILE_TRACER()" and bypass Steven's preprocessing stage. Is this workable and/or a good idea? Dave Jenkins

Dave Jenkins wrote:
"David Abrahams" <dave@boostpro.com> wrote in message news:m28wmbf91i.fsf@boostpro.com...
on Tue Apr 07 2009, "troy d. straszheim" <troy-AT-resophonic.com> wrote:
Gevorg Voskanyan wrote:
How about a macro BOOST_PROTO_EXTRA_CHECKING or something like that to have those kind of checks conditionally?
I could see a BOOST_MPL_DISABLE_ASSERTS token, behavior analogous to BOOST_DISABLE_ASSERTS.
It's a very good idea, IMO. Open a ticket?
This flag sounds the same as the BOOST_COMPILE_TIME_DEBUG flag proposed by Eric Niebler here: http://lists.boost.org/boost-users/2009/01/44451.php. Joel de Guzman suggested making it an integer (0 == no CT debug, 1..3 CT debug levels) here: http://lists.boost.org/boostusers/2009/01/44452.php.
My thought is to have one of the integer debug levels enable compile-time tracing of "interesting" template instantiations using Steven Watanabe's template_profiler. For this to work, the library author would have to mark the "interesting" template classes and functions with "PROFILE_TRACER()" and bypass Steven's preprocessing stage. Is this workable and/or a good idea?
Interesting ideas... At first glance it still seems to me like stuff that belongs in the MPL. I could see an MPL_TRACE() macro that expanded by default to nothing. The user could set it as appropriate to use Steven's tracer or some future tracer, for instance one built in to clang. I'm not sure I agree with the debug-levels idea, as these are asserts, not warning severity levels. If they were warnings, it is still difficult to coordinate between developers, ie I don't really know if I'm using level '2' to mean the same level of 'debugginess' as somebody else is. It is also impossible to enforce. In the case where debug levels are going to regulate the number of traces you see, I don't see that as very useful either, since when tracing template instantiations you're dealing with a spectacular amount of compiler-spew no matter what. Now, per-class trace control (maybe via a trait?) this would be imho more useful. -t

troy d. straszheim wrote:
Now, per-class trace control (maybe via a trait?) this would be imho more useful.
Here's a possible interface for a boost::mpl-ized version of Steven Watanabe's template_profiler: #define BOOST_MPL_ENABLE_TRACE #include "trace.hpp" // // classes peppered with traces // template <typename T> struct traceme { BOOST_MPL_TRACE(traceme<T>); }; template <typename T> struct traceme_too { BOOST_MPL_TRACE(traceme_too<T>); }; template <typename T> struct dont_trace_me { BOOST_MPL_TRACE(dont_trace_me<T>); }; // // trace-enabling traits // namespace boost { namespace mpl { namespace trace { template <typename T> struct enable<traceme<T> > : boost::mpl::true_ { }; template <typename T> struct enable<traceme_too<T> > : boost::mpl::true_ { }; } } } // // 3. profit // int main(int, char**) { traceme<int> ti; dont_trace_me<float> dtmf; traceme_too<void> tv; } The trace.hpp is attached, tested on gccs 4.3 and 4.2. -t

AMDG troy d. straszheim wrote:
Here's a possible interface for a boost::mpl-ized version of Steven Watanabe's template_profiler:
#define BOOST_MPL_ENABLE_TRACE #include "trace.hpp"
// // classes peppered with traces // template <typename T> struct traceme { BOOST_MPL_TRACE(traceme<T>); };
<snip>
The trace.hpp is attached, tested on gccs 4.3 and 4.2.
Unfortunately this doesn't work well with function templates and it's more difficult to generate automatically. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
troy d. straszheim wrote:
Here's a possible interface for a boost::mpl-ized version of Steven Watanabe's template_profiler:
#define BOOST_MPL_ENABLE_TRACE #include "trace.hpp"
// // classes peppered with traces // template <typename T> struct traceme { BOOST_MPL_TRACE(traceme<T>); };
<snip>
The trace.hpp is attached, tested on gccs 4.3 and 4.2.
Unfortunately this doesn't work well with function templates
Hrm, quite right.
and it's more difficult to generate automatically.
I suppose I wasn't really thinking about 'profiling' total number of template instantiations, more about getting template stack traces while debugging... well maybe I wasn't thinking at all, I just wanted to have a go at it. -t

AMDG troy d. straszheim wrote:
I suppose I wasn't really thinking about 'profiling' total number of template instantiations, more about getting template stack traces while debugging... well maybe I wasn't thinking at all, I just wanted to have a go at it.
There's already a boost::mpl::print... In Christ, Steven Watanabe

AMDG Dave Jenkins wrote:
This flag sounds the same as the BOOST_COMPILE_TIME_DEBUG flag proposed by Eric Niebler here: http://lists.boost.org/boost-users/2009/01/44451.php. Joel de Guzman suggested making it an integer (0 == no CT debug, 1..3 CT debug levels) here: http://lists.boost.org/boostusers/2009/01/44452.php.
My thought is to have one of the integer debug levels enable compile-time tracing of "interesting" template instantiations using Steven Watanabe's template_profiler. For this to work, the library author would have to mark the "interesting" template classes and functions with "PROFILE_TRACER()" and bypass Steven's preprocessing stage. Is this workable and/or a good idea?
I've been slowly working on getting the call graph info working. In order to do this correctly I have to parse the warning backtrace. This mechanism I am using will break if not every template instantiation is traced. In Christ, Steven Watanabe
participants (6)
-
Dave Jenkins
-
David Abrahams
-
Eric Niebler
-
Gevorg Voskanyan
-
Steven Watanabe
-
troy d. straszheim