Giter VIP home page Giter VIP logo

Comments (6)

correaa avatar correaa commented on July 30, 2024

This is more input/output (io) than and serialization. This is not implemented probably because it requires a pretty complicated parser of units and the result can be error prone. For example, in the most flexible cases requires numeric/unit conversions. It is not clear if inconsistent input out would allowed and the gain is marginal after a lot of work and a lot of assumptions.

Having said that, Boost.Serialization supports serialization and deserialization of Boost.Units but not for human consumption.

from units.

FlorentTomi avatar FlorentTomi commented on July 30, 2024

I'm not really talking about parsing, for example, "10 m" into a feet quantity, but at least having the simple case of allowing parsing "10 m" into a meter quantity.
Shouldn't it be only a matter of checking the prefix, and parsing the numeric value ?

from units.

correaa avatar correaa commented on July 30, 2024

I'm not really talking about parsing, for example, "10 m" into a feet quantity, but at least having the simple case of allowing parsing "10 m" into a meter quantity.
Shouldn't it be only a matter of checking the prefix, and parsing the numeric value ?

Not really, there are a lot of variables that can spoil the apparent simplicity. For example the format of the output depends on the files that are included for example

std::cout << 3.14*si::joule << std::endl 

outputs "3.14 m^2 kg s^-2". but if you #include<boost/units/systems/si/io.hpp> it will output 3.14 J. So which of the two should be checked against? not to mention other surprising behavoir relative to scaled quantities (for example an input with 3.14e6 ยตJ).

I would say that in the best imaginable case human input will always give surprising results, the main problem is that the parser will have to have a lot of compile time information about all possible ways to interpret and disambiguate unit initials, etc.

Having said that, yes you can in principle be very strict and only accept input that exactly matches the output, at least for the unit portion. Again, with the caveat that many configuration variables can affect the output format. But if you promise the input and output will occur with the same compilation configuation perhaps you can accept this implementation below.

This solves your problem the way you want but it also shows the exceeding number of assumptions made but this simple parser. This is not at the quality or generality level expected for a library like Boost.Units, so it is probably a good thing that they decided to leave input from streams unimplemented.

namespace boost{ 
namespace units{ // I am stomping over boost.units namespace for simplicity
template<class U, class T>
std::istream& operator>>(std::istream& is, quantity<U, T>& q){
	typename quantity<U, T>::value_type val; is >> val;
	std::string const expected = to_string(U{});
	std::string tag(expected.size()+1, 0); is.get(&tag[0], tag.size()+1);
	if(tag[0]==' ' and tag.substr(1)==expected){
		q = quantity<U, T>::from_value(val);
	}else{
	//	std::cerr<<"error expected "<< expected <<", got "<< tag <<std::endl;
		is.setstate(std::ios::failbit);
	}
	return is;
}
}}

int main(){
	{
		quantity<si::length> l = 3.14*si::meter;
		std::stringstream ss; ss << l << "abc" << std::endl;

		quantity<si::length> l2; ss >> l2; 
		assert(ss and l == l2);

		std::string check; ss >> check; assert(check=="abc");
	}
	{
		quantity<si::energy> e = 5.24*si::joule;
		std::stringstream ss; ss << e << "abc" << std::endl;
		// promise not do funny stuff between write and read, like including new units/io headers
		quantity<si::energy> e2; ss >> e2; 
		assert(ss and e == e2);

		std::string check; ss >> check; assert(check=="abc");
	}
}

from units.

correaa avatar correaa commented on July 30, 2024

This reminded me that I have some code that I did not update to the gitlab repository with my custom extensions to boost.units. The code I presented above is now here:
https://gitlab.com/correaa/boost-units/blob/master/io/input.hpp

This also includes another feature which I think is more sane than general input, which it to leave the user to generate dimensionless expressions in which the normal input can be performed.

For example,

suppose you know a certain input ("5") is in micro meters. Then you get the variable in meters.

quantity<si::length> l; in >> l/(si::micro*si::meter); assert( l == 5e-6*si::meter );

So as long as you can generate a dimensionless expression (ok, by division only for the moment) then this will work. I think this is better than investing in a general input parser for a lot of work that is going be thrown away since the compile time type cannot be changed anyway.

from units.

FlorentTomi avatar FlorentTomi commented on July 30, 2024

Thank you for the code and these complete answers, this should do the trick.

If I were to give my two cents, I would say that the way IO is handled by the library is either too complicated or too "sneaky". Just including a header shouldn't, imho, change the results of an operation. If it's just to change the way units output themselves, wouldn't it be just fine, for example, to create new stream flags ?

I agree with you that maybe, handling dimensionless quantities are more sane, as IO should be well documented and as clear as possible.

from units.

correaa avatar correaa commented on July 30, 2024

from units.

Related Issues (16)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.