GithubHelp home page GithubHelp logo

C++17 ideas? about units HOT 14 CLOSED

nholthaus avatar nholthaus commented on September 17, 2024
C++17 ideas?

from units.

Comments (14)

Morwenn avatar Morwenn commented on September 17, 2024 2

There are a few metaprogramming utilities that can find their place into the library:

  • You can replace std::integral_constant<bool, ...> by std::bool_constant<...>
  • You can use the standard std::void_t instead of reimplementing it
  • std::conjunction and friends can improve std::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 replace all_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.

nholthaus avatar nholthaus commented on September 17, 2024 1

@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.

EvanBalster avatar EvanBalster commented on September 17, 2024 1

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.

Morwenn avatar Morwenn commented on September 17, 2024 1

@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.

nholthaus avatar nholthaus commented on September 17, 2024

Good stuff, especially the reminders about things like units::void_t which could break the library in C++17.

from units.

Morwenn avatar Morwenn commented on September 17, 2024

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.

ax3l avatar ax3l commented on September 17, 2024

Support for a CT/RT std::array with all attributes using the same unit would be great.

from units.

nholthaus avatar nholthaus commented on September 17, 2024

@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.

Morwenn avatar Morwenn commented on September 17, 2024

One way to get better names is to use small structs and inheritance instead of typedef or type aliases, but it very occasionally affects the semantics.

from units.

nholthaus avatar nholthaus commented on September 17, 2024

@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.

EvanBalster avatar EvanBalster commented on September 17, 2024

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.

nholthaus avatar nholthaus commented on September 17, 2024

@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.

EvanBalster avatar EvanBalster commented on September 17, 2024

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.

Morwenn avatar Morwenn commented on September 17, 2024

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)

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.