Comments (14)
There are a few metaprogramming utilities that can find their place into the library:
- You can replace
std::integral_constant<bool, ...>
bystd::bool_constant<...>
- You can use the standard
std::void_t
instead of reimplementing it std::conjunction
and friends can improvestd::enable_if
in some places, and their short-circuiting behaviour may even be desirable (I didn't check)- Actually
std::conjunction
looks like it could replaceall_true
if I'm not mistaken about what it's intended to do (fold expressions might be a better choice depending on the use case) - The new variable templates
*_v
can shorten the code in some places, which often eases reading metaprogramming code - Same remark for
*_t
type aliases (e.g.std::enable_if_t
), but you can already use them in C++14 today
from units.
@ax3l I'm not sure I know specifically what you mean. The following is already possible in v2.2.0
of the library:
TEST_F(UnitContainer, constexprStdArray)
{
constexpr std::array<meter_t, 5> arr = { 0_m, 1_m, 2_m, 3_m, 4_m };
EXPECT_EQ(arr[3], 3_m);
}
Could you point me to some more info or syntax examples about what's expected from a c++17 constexpr std::array
?
In general, unit_t
types should play very nicely with std
containers and algorithms because they are trivial types (which you can verify with the std::is_trivial
trait on compilers which fully support it).
from units.
My primary request would be to leverage features that allow for clearer error messages. Type checking is essentially the purpose of the units library, but quite often the compiler will emit excessively verbose template errors that can make the actual problem difficult to understand, especially when dealing with many different units at once. (I'm doing some fluid dynamics simulation and have run afoul of this once or twice.)
I may open a separate issue discussing this matter.
from units.
@nholthaus You can make a local struct inherit from a template parameter type, but that's a bit dangerous since not every type template parameter is a class, and even a class might be declared final
.
On the other hand, when you have full control over the type you inherit from, struct
is a reasonable strong typedef
:
struct angular_velocity_unit:
base_unit<std::ratio<0>, std::ratio<0>, std::ratio<-1>, std::ratio<1>>
{};
However, whenever you need to pass an angular_velocity_unit
to something that expects a base_unit<T>
, you have to make sure that one does not have an explicit check along the lines of std::is_same<unit_base<T>, U>::value
. IOW it should be fine most of the time, and you can probably handle the few potentially problematic problems with care.
Im my experience, compiles are more prone to use angular_velocity_unit
if you define it as a struct
than base_unit<std::ratio<0>, std::ratio<0>, std::ratio<-1>, std::ratio<1>>
. Well, it might still vomit the whole template if there is an error specifically with one of the tempate parameters.
As a side note, I have read in some CppCon slides that using a struct
as a strong typedef
sometimes improves compile times because when making type name comparisons, the compiler will compare the new name instead of the full template + its parameters. Apparently it may be worth it when you have long template instanciations (I haven't tested these claims though).
from units.
Good stuff, especially the reminders about things like units::void_t
which could break the library in C++17.
from units.
I just reemembered about it, but there will be a three-argument overload to std::hypot
in C++17. You surely want to add such a function to the math functions.
from units.
Support for a CT/RT std::array
with all attributes using the same unit would be great.
from units.
@EvanBalster Please do. The primary facility to "fail" an incompatible operation is a static_assert
in the convert()
function saying that unit types aren't compatible. However, I've also experienced that error being buried pretty deep down from the actual problem site.
It wouldn't be hard (for many cases) to add additional static_assert
cases higher into the chain, with possibly clearer error messages (like in fdim()
). The hardest part is just identifying those places.
The other big problem I've seen is compilers not interpreting the base_unit
typedef aliases, and instead printing out streams of base_unit<std::ratio<0>, std::ratio<0>, ...
. I've done by best to use typedef
instead of aliases, but a lot of how those errors are reported depends on the compilers themselves.
Use of static_assert
(possibly based on the type-traits, e.g. is_length_unit<...>::value
) in your own code that consumes units
may also be helpful.
from units.
One way to get better names is to use small struct
s and inheritance instead of typedef
or type aliases, but it very occasionally affects the semantics.
from units.
@Morwenn can that be used for something like naming a template parameter type? Either way I could probably refactor the category
namespace to use structs with little effort, but I don't have a very good test case to see if the errors are improved. @EvanBalster why don't you post a particularly bad example and we'll give it a shot.
from units.
Actually, the verbosity problem I mention still applies even when it's a static_assert. As you say, compilers prefer to vomit out the whole template, and have few other options when it's a derived type without any typedef whatsoever.
My line of inquiry in #64 is somewhat more... extreme. Rather than covering up the issue with typedefs, I'm suggesting a re-structuring of the base_unit template to make it more lightweight and human-readable.
from units.
@Morwenn looking back through the implementation, almost everything depends on partial specialization of the base_unit
class, so this is going to need some serious thought and prototyping.
from units.
I've implemented two approaches to variadic dimension templates in #64. The second is very promising, I think:
using force = base_unit<length, std::ratio<1>, mass, std::ratio<1>, time, std::ratio<-2>>;
Code here: https://github.com/EvanBalster/units_variadic_test
(With working implementations of type transformation for multiply, divide, pow, inverse)
from units.
Just a note: UTF-8 literals can't be used for special characters. They're only allowed for UTF-8 characters are also ASCII characters. The goal is to guarantee the encoding of such characters; there was no mean to actually guarantee this encoding before C++17.
You can't use UTF-8 literals for any character that would be >7bits; that issue was totally sidestepped.
from units.
Related Issues (20)
- 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
- Units are not installed as a system library HOT 1
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.