Comments (8)
You could look at Howard Hinnant's date library. IIRC there's a IO part that handles µs
smoothly for microseconds. He may have used an elegant and portable solution.
from units.
I'd like to note that having a way of extracting units without std::ostream
would be nice for embedded applications. The regex solution is even less applicable there.
from units.
First, let's solve your problem at hand. Then I'll provide some explanation of why those things are the way they are.
The easiest way to do want you want is to write a small function to parse the stream output of a unit value:
#include <sstream>
#include <regex>
#include <tuple>
template<typename T>
std::tuple<std::string, std::string> parseUnit(T val)
{
static_assert(units::traits::is_unit_t<T>::value, "val must be a unit_t type.");
static std::regex unitRegex(R"((.*)\s+(.*))");
std::stringstream ss;
std::string s;
std::smatch matches;
ss << val;
s = ss.str();
if (std::regex_match(s, matches, unitRegex))
{
if (matches.size() == 3)
{
// to be extra fancy, replace "deg" in matches[2] (if found) with "°"
return std::make_tuple(matches[1], matches[2]);
}
}
return std::make_tuple("", "");
}
and then usage would be like so:
int main()
{
millimeter_t myDist(42);
auto unitTuple = parseUnit(myDist);
std::string val, abbreviation;
std::tie(val, abbreviation) = unitTuple;
if(val == "42")
std::cout << "value is correct" << std::endl;
if(abbreviation == "mm")
std::cout << "abbreviation is correct" << std::endl;
}
Why not just access the abbreviation directly?
One of the benefits of a compile time unit library like this is that, well, all the work is done at compile time. This means that in terms of storage and efficiency, using units has the same cost of using double
values. Which means that the abbreviation isn't ever actually instantiated or stored anywhere, so it can't be accessed in any type of direct way.
The only thing that actually knows the string abbreviation is the unit's overloaded operator<<
, so the easiest way to get the abbreviation back out is to <<
the unit into a stringstream
and parse it with a very simple regular expression
. Hard ways could include having some type of tag dispatch function or wrapping the ADD_UNIT
macro with something that saves the abbreviation for you.
The above parse function should be fine for most applications.
Why not use UTF-8?
The technical answer is that the unit literals are made from the unit abbreviation, and literals are limited to an underscore followed by a lower-case letter in c++11
, and an underscore followed by a letter in c++14
. I couldn't even make _%
work as a literal (which made me sad).
Could we split the literal abbreviation from the string abbreviation? Yeah, with some additional complexity. However, as a library author, I can't really force your project settings to support UTF-8, and I would get a bunch of "units print gibberish" issues. While I certainly agree it's sub-optimal, "degC" and least prints for everyone and is relatively understandable.
Would I pull something that split the literal/printed abbreviations if it handled different text encoding incredibly gracefully? You bet!
from units.
@Morwenn I'll take a look.
from units.
The library uses ascii character 181 for µ (see line 6937 ff).
from units.
with c++17 you could do that easily enough for your most common unit types using if constexpr()
. There's not much to be done on the library side as the abbreviation isn't actually stored anywhere (to maintain equivalent performance to double
), so there's no way to access it outside of that one macro.
from units.
Right, constexpr if could certainly help. I was also thinking maybe having a member function returning char const *
:
constexpr char const * t() {
return "asd";
}
Would that affect performance?
from units.
In v2.3 there is a to_string
overload that will do the following:
auto a = 3.5_m;
auto str = units::length::to_string(a);
std::cout << str; // prints "3.5 m"
also abbreviation
which does:
auto a = 3.5_m;
auto str = units::length::abbreviation(a);
std::cout << str; // prints "m"
to keep compile-time down, these are defined for each unit in the unit category namespace. It's only going to work for library defined units. Hopefully works for most use cases.
from units.
Related Issues (20)
- 2.3.2 Fails to compile HOT 2
- Conan package out of date HOT 2
- Undefined references to .name() and .abbreviation() HOT 1
- Incorrect enable_if condition for operator+ HOT 1
- Request for branch and pull request permissions HOT 5
- percent_t FROM double and TO double are different HOT 9
- 2.3.3 does not compile
- Add a way to specify units when "downcasting" to numeric type HOT 2
- Support the MSFS SDK HOT 2
- Empty base class optimization for MSVC
- Does not compile with GCC 12 HOT 1
- raw() and value() is error prone HOT 4
- [Bug] i386 (32-bit) fails to compile
- Shouldn't the naming of units::torque::foot_pound be changed
- v2 -> v3 porting HOT 2
- Need help implementing resistance as a new custom unit. HOT 2
- unit conversion emits a surprisingly high amount of instructions
- Compilation under MINGW
- Math functions not compatible with percent HOT 1
- Status of the project HOT 14
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from units.