
Giovanni Bajo wrote:
Arkadiy Vertleyb wrote:
One more addition to the typeof library is a macro, that, unlike BOOST_TYPEOF(), which removes top-level consts and references, attempts to be closer to the decltype, by preserving lvalue-ness of its argument:
BOOST_TYPEOF_PRESERVE_LVALUE(expr)
I do admit that the name is quite clumzy :(
BOOST_DECLTYPE?
Well, unfortunately, it's not exactly decltype :( In particular: int i; const int ci = 0; decltype BOOST_TYPEOF_PRESERVE_LVALUE -------- ---------------------------- i int int& ci const int const int& etc. It is calculated by binding a T& to the expression. If it can't be bound the type is the same as one returned by BOOST_TYPEOF. If it can, it's either reference or const reference, depending on the constness of T. Any suggestions how to make it closer to the real decltype? Arkadiy

On Jul 22, 2004, at 8:08 AM, Arkadiy Vertleyb wrote:
Giovanni Bajo wrote:
Arkadiy Vertleyb wrote:
One more addition to the typeof library is a macro, that, unlike BOOST_TYPEOF(), which removes top-level consts and references, attempts to be closer to the decltype, by preserving lvalue-ness of its argument:
BOOST_TYPEOF_PRESERVE_LVALUE(expr)
I do admit that the name is quite clumzy :(
BOOST_DECLTYPE?
Well, unfortunately, it's not exactly decltype :(
In particular:
int i; const int ci = 0;
decltype BOOST_TYPEOF_PRESERVE_LVALUE -------- ---------------------------- i int int& ci const int const int&
etc.
It is calculated by binding a T& to the expression. If it can't be bound the type is the same as one returned by BOOST_TYPEOF. If it can, it's either reference or const reference, depending on the constness of T.
First of all, this is really cool. My initial reaction to the typeof lib was "cool, we have typeof" but "darn, I can't use it for result_of". Whatever we name this macro, it's directly usable for result_of. That's great! As for naming: It could just be called BOOST_DECLTYPE, with the caveat that it doesn't act quite perfectly for variables. Frankly, I couldn't care much less about variables: you rarely need the type of those, although I could easily contrive cases. BOOST_LVALUE_TYPEOF might be the most obvious name: it returns a reference if it gets an lvalue, a non-reference otherwise. Doug

Doug Gregor <dgregor@cs.indiana.edu> writes:
First of all, this is really cool. My initial reaction to the typeof lib was "cool, we have typeof" but "darn, I can't use it for result_of". Whatever we name this macro, it's directly usable for result_of. That's great!
That's exactly why I pushed Arkadiy to implement this lvalue stuff :) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

"Doug Gregor" <dgregor@cs.indiana.edu> wrote
On Jul 22, 2004, at 8:08 AM, Arkadiy Vertleyb wrote:
[snip]
It could just be called BOOST_DECLTYPE, with the caveat that it doesn't act quite perfectly for variables. Frankly, I couldn't care much less about variables: you rarely need the type of those, although I could easily contrive cases.
I want variables! In context of my physical quantities library types resulting from calcs are computed in non-trivial ways. If the programmer has a complicated calculation then declaring a variable may force a scaling q_area::mm2 a; q_length:: mm b; q_length::m c = a / b; In the above, the temporary result of a / b will be divided by 1000 in the assign to cc, because the programmer has forced this by the l_value assignment,but: auto c = a / b; Here, the resulting units of the temporary are automatically computed., no scaling. In this case units of millimetres( I think... all these assertions require manual checking) would be the auto type, but the programmer doesnt need to worry about it. ie every non-auto assignment represents a potential loss in speed and accuracy. This is a major potential useage of the mechanism in my physical quantities library. FWIW I am very interested in BOOST_TYPEOF but unfortunately dont have time to investigate for a couple of weeks. regards Andy Little

I want variables! In context of my physical quantities library types resulting from calcs are computed in non-trivial ways. If the programmer has a complicated calculation then declaring a variable may force a scaling
q_area::mm2 a; q_length:: mm b; q_length::m c = a / b;
In the above, the temporary result of a / b will be divided by 1000 in
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote the
assign to cc, because the programmer has forced this by the l_value assignment,but:
auto c = a / b;
I don't think you really want lvalues. You would only want to preserve lvalue if you want to do something like: a /b = 5; and I don't think that is what you want. The "auto" is implemented via typeof, not via decltype. So your type is always a value. If you want a reference, you explicitly specify this: int& foo(); auto p = foo(); // int auto& p = foo(); //int& The same can be emulated with BOOST_AUTO: BOOST_AUTO(p, foo());// int BOOST_AUTO(&p, foo());//int& Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
I don't think you really want lvalues. You would only want to preserve lvalue if you want to do something like:
a /b = 5;
and I don't think that is what you want.
Ah yes ... I am ever ignorant of the what the term 'l_value' means. Only thing I can think of is stream output via <<, May be wrong but ostream& is then an l_value? Whether that causes problems I have no idea. Whatever. I would hope it tries to get as close as it can to the decltype and auto proposals as possible, because.. bearing in mind that it may quite cumbersome to use in larger programs, I still see it as being very useful for demos and experimenting with ie to say "if we had decltype or whatever, you could do this, this and this. " . as a prelude to the real thing. That anyway is how I would probably use it.( And in fact would find it very useful to "look into the future"). I would tend to avoid it in larger programs due to compile times. (Only because other libraries drags things down enough already). I think spirit and lambda already have their own type deduction schemes, making it easy to implement there. IOW It might be useful to grab another library ie UBLAS etc and try to implement the mechanism there to find/ show what problems other users may have in implementing it. The "User interface" seems to be the part that is lacking at the moment... but I guess thats old news. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
...I think spirit and lambda already have their own type deduction schemes, making it easy to implement there.
I am unaware of such schemes.
The "User interface" seems to be the part that is lacking at the moment... but I guess thats old news.
The "User interface", at the moment, consists of 5 (pretty easy to use, I think) macros: BOOST_TYPEOF(expr) BOOST_AUTO(var, expr) BOOST_TYPEOF_PRESERVE_LVALUE(expr) BOOST_TYPEOF_REGISTER_TYPE(T) BOOST_TYPEOF_REGISTER_TEMPLATE(Name, nParams) and whatever we deside to go with in terms of ID generation. What exactly is lacking? Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
...I think spirit and lambda already have their own type deduction schemes, making it easy to implement there.
I am unaware of such schemes.
I dont know about spirit but lambda has: template<> struct plain_return_type_2< boost::lambda::arithmetic_action< boost::lambda::plus_action >
{ typedef ... type; };
etc which is IMO a type deduction scheme. I guess Spirit has one because Joel de Guzman has type_deduction.hpp in the boost sandbox. UBLAS probably has or soon will have one. result_of is another. And I decided to do my own because you can never have too much of a good thing IMO.
What exactly is lacking?
Nothing... Its perfect :-) regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
...I think spirit and lambda already have their own type deduction schemes, making it easy to implement there.
I am unaware of such schemes.
I dont know about spirit but lambda has: template<> struct plain_return_type_2< boost::lambda::arithmetic_action< boost::lambda::plus_action >
{ typedef ... type; };
etc which is IMO a type deduction scheme.
I think (and please correct me if I am wrong) this allows to determine return type rather than the type of the expression itself. Take the following Lambda functor: _1 > 15 && _2 < 20 It's return type is "bool". The type of the functor itself is (please get ready): lambda_functor< lambda_functor_base< logical_action<and_action>, tuple< lambda_functor< lambda_functor_base< relational_action<greater_action>, tuple< lambda_functor<placeholder<1> >, int const > > >, lambda_functor< lambda_functor_base< relational_action<less_action>, tuple< lambda_functor<placeholder<2> >, int const > > > > >
If you want to allocate a named object of this type (provided you don't want to use Boost.Function, which imposes runtime penalties), you have to write this in your code. OTOH, With auto you would just write: auto f = _1 > 15 && _2 < 20; // the compiler computes type for you And with the library we are corrently discussing: BOOST_AUTO(f, _1 > 15 && _2 < 20); Which is not such a bad approximation, IMO.
What exactly is lacking?
Nothing... Its perfect :-)
:-)) Regards, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
OTOH, With auto you would just write:
auto f = _1 > 15 && _2 < 20; // the compiler computes type for you
And with the library we are corrently discussing:
BOOST_AUTO(f, _1 > 15 && _2 < 20);
Which is not such a bad approximation, IMO.
I will definitely aim to try it out in depth with my physical quantities library in VC7.1, hopefully within couple of weeks. Two obvious points to look for are 1) How easy is it for the user (ie me) to implement in practise. 2) How much does it affect compile times. Because my library is not boosted it will be a more interesting test. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
I will definitely aim to try it out in depth with my physical quantities library in VC7.1, hopefully within couple of weeks. Two obvious points to look for are
1) How easy is it for the user (ie me) to implement in practise.
Quite easy, IMO, and totaly non-intruisive. You just have to tell the typeof library about your types (name) and templates (name and the number of parameters). For the example with Lambada, that I provided before, this would mean to write something like following: BOOST_TYPEOF_REGISTER_TEMPLATE(boost::tuples::tuple, 2); BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::lambda_functor, 1); BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::lambda_functor_base, 2); BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::relational_action, 1); BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::logical_action, 1); BOOST_TYPEOF_REGISTER_TEMPLATE(boost::lambda::other_action, 1); BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::greater_action); BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::less_action); BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::and_action); BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::placeholder<1>); BOOST_TYPEOF_REGISTER_TYPE(boost::lambda::placeholder<2>); After this you can use any combination of registered types/templates (and primitive types, which are registered by the typeof library) -- the system will be able to process it.
2) How much does it affect compile times.
Well, it does affect it. On my 1.5GHZ PC, VC7.1, it takes 2 to 3 sec to process the above-mentioned Lambda expression (I do not count the time needed to #include my stuff, as well libraries that I use -- in VC7.1 you can almost eliminate it by using pre-compiled headers).
Because my library is not boosted it will be a more interesting test.
OK, but I assure you that there is nothing in the typeof system that makes it easier to use with boostified libraries. Regards, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message news:cdtgnq$qit$1@sea.gmane.org...
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
1) How easy is it for the user (ie me) to implement in practise.
Quite easy, IMO, and totaly non-intruisive. You just have to tell the typeof library about your types (name) and templates (name and the number of parameters).
What I'm not quite clear about yet is how much of the stuff in my library I will actually need to register. Presumably the actual types of template parameters only used internally arent required? Whatever... I will let you know how I get on. regards Andy Little
participants (4)
-
Andy Little
-
Arkadiy Vertleyb
-
David Abrahams
-
Doug Gregor