Physical Boost.Units Custom Literals

Now that we soon have user literals (UDLs), for example in GCC 4.7, I look forward to (physical) element libraries (such as Boost.Units ), using them to facilitate the expression of literals such as 1+3i , 3m , 3meter or 13_meter . Has anyone written the Boost.Units extension using a UDL that supports this behavior?

+7
source share
2 answers

No one came out with such an extension. Only gcc (and possibly IBM?) Has a UDL, so there may be time. I hope some units turn it into tr2, which starts now. If this happens, I am sure that UDL for devices will appear.

It works:

 // ./bin/bin/g++ -std=c++0x -o units4 units4.cpp #include <boost/units/unit.hpp> #include <boost/units/quantity.hpp> #include <boost/units/systems/si.hpp> using namespace boost::units; using namespace boost::units::si; quantity<length, long double> operator"" _m(long double x) { return x * meters; } quantity<si::time, long double> operator"" _s(long double x) { return x * seconds; } int main() { auto l = 66.6_m; auto v = 2.5_m / 6.6_s; std::cout << "l = " << l << std::endl; std::cout << "v = " << v << std::endl; } 

I think it would not be too difficult to go through your favorite units and do it.

Regarding placing them in the library: Literal operators are functions of the namespace area. Suffix competition will become ugly. I would (if I had been encouraged) have

 namespace literals { ... } 

Boost users can then perform

 using boost::units::literals; 

along with all the others through the ads you usually use. Then you will not get clobbered on std::tr2::units , for example. Similarly, if you roll back your own.

+5
source

In my opinion, there is not much gain in using literals for Boost.Units because a stronger syntax can be achieved with existing features.

In simple cases, it seems that literals are the way to go, but soon you will see that it is not very powerful. For example, you still need to define literals for combined units, for example, how do you express 1 m / s (one meter per second)?

Currently

 auto v = 1*si::meter/si::second; // yes, it is long 

but with literals?

 // fake code using namespace boost::units::literals; auto v = 1._m_over_s; // or 1._m/si::second; or 1._m/1_s // even worst 

A better solution can be achieved with existing features. And this is what I do:

 namespace boost{namespace units{namespace si{ //excuse me! namespace abbreviations{ static const length m = si::meter; static const time s = si::second; // ... } }}} // thank you! using namespace si::abbreviations; auto v = 1.*m/s; 

You can do the same in the same way: auto a = 1.*m/pow<2>(s); or expand the abbreviations more if you want (for example, static const area m2 = pow<2>(si::meter); )

What else is needed for this?

Perhaps a combined solution may be a way

 auto v = 1._m/s; // _m is literal, /s is from si::abbreviation combined with operator/ 

but there will be so much redundant code, and the gain is minimal (replace * with _ after the number.)

One of the drawbacks of my solution is that it swaps the namespace with common names of one letter. But I don’t see a way around this, except to add an underscore (to the beginning or end of the abbreviation), as in 1.*m_/s_ , but at least I can build real unit expressions.

+3
source

All Articles