Skip to content

Attribute: Implement get<>() Cast#345

Merged
ax3l merged 4 commits intoopenPMD:devfrom
ax3l:topic-getAttributeCast
Sep 14, 2018
Merged

Attribute: Implement get<>() Cast#345
ax3l merged 4 commits intoopenPMD:devfrom
ax3l:topic-getAttributeCast

Conversation

@ax3l
Copy link
Member

@ax3l ax3l commented Sep 13, 2018

Close #335: Implement getCast<>() in Attribute::get<U>(). Will now cast
during ::get<U>() if convertible.

Implementations can now simply use ::get<>() again :)
Final clean-up for refactoring started in #337

@ax3l ax3l requested a review from anokfireball September 13, 2018 20:40
@ax3l ax3l force-pushed the topic-getAttributeCast branch 3 times, most recently from 8ae9d20 to 45b7e04 Compare September 13, 2018 21:37
@ax3l
Copy link
Member Author

ax3l commented Sep 14, 2018

@C0nsultant Ping :)

@anokfireball
Copy link
Member

This make Attributable::readFloatingPoint() redundant. The casting logic applied therein is now handled in get itself. I'll do a follow-up PR that removes this redundancy and just uses get.

template< typename U >
U Attribute::get() const
{
return getCast< U >( Variant::getResource() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would hate to cast silently here and not notify the user about possible loss of precision.
There already is a function that does this (warnWrongDtype()). I'll push a patch shortly that will use that function if the resource dtype and U differ.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually not what I would like as a user.
If there is an attribute "attr" I can RT check it's dtype. If I want to get<> it as something, I want to get it as exactly such.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have a quick chat on the philosophy of that method if you like :) Gitter? VC?
In case you are busy today, we can also chat on Monday. I have to leave here around noon.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offline resolution:
C++ requires a certain effort from the user to put the type inside the brackets. Thus, he should be well aware of what he is requesting.
Information about the datatype can be obtained at run-time. If non-casting behavior is desired, we shift this obligation to the user.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If non-casting behavior is desired, we shift this obligation to the user.

e.g. by checking the dtype at runtime, taking the resource directly or casting back to the underlying auxiliary::Variant that will throw.

REQUIRE(getCast< std::vector< long double > >(s.getAttribute("vecLongdouble")) == std::vector< long double >({0.L, std::numeric_limits<long double>::max()}));
REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, std::numeric_limits<long double>::max()}));
REQUIRE(s.getAttribute("vecString").get< std::vector< std::string > >() == std::vector< std::string >({"vector", "of", "strings"}));
// REQUIRE(s.getAttribute("bool").get< bool >() == true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work as expected now, as the stored uint8_t can be cast to bool in the new get.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just need to rebase, done already in #344

Implement `getCast<>()` in `Attribute::get<U>()`. Will now cast
during get if convertible.
getCast is now convieniently implemented in ::get
Added this for being pedantic in case this causes a warning.
Nevertheless, would have to create a factory here to properly
init a `std::array`.
@ax3l ax3l force-pushed the topic-getAttributeCast branch from 45b7e04 to 78c7a2f Compare September 14, 2018 08:48
REQUIRE(s.getAttribute("vecLongdouble").get< std::vector< long double > >() == std::vector< long double >({0.L, std::numeric_limits<long double>::max()}));
REQUIRE(s.getAttribute("vecString").get< std::vector< std::string > >() == std::vector< std::string >({"vector", "of", "strings"}));
REQUIRE(s.getAttribute("bool").get< unsigned char >() == true);
REQUIRE(s.getAttribute("boolF").get< unsigned char >() == false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now can be retrieved as bool, thanks to the casting get.

Have this in my staged set, will push soon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds great, thanks! :)

Datatype store,
Datatype request)
{
std::cerr << "Warning: Attribute '" << key
Copy link
Member Author

@ax3l ax3l Sep 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loving MSVC:

error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion

forgot to include <string>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed it :)

The handling an casting of arbitrary-width floating-point Attributes is
now redundant with the casting that is present in Attrbute::get.
@ax3l ax3l force-pushed the topic-getAttributeCast branch from 4b3a053 to f67e00e Compare September 14, 2018 09:52
@ax3l ax3l merged commit 4da295b into openPMD:dev Sep 14, 2018
@ax3l ax3l deleted the topic-getAttributeCast branch September 14, 2018 11:36
ax3l added a commit to ax3l/openPMD-api that referenced this pull request Jun 8, 2022
In `pybind11`, overloads on types are order-dependent (first wins).
pybind/pybind11#1512

We specialize `double` here generically and cast in read if needed
(see openPMD#345 openPMD#1137).

Later on, we could add support for 1D numpy arrays with distinct
type.
ax3l added a commit that referenced this pull request Dec 20, 2022
In `pybind11`, overloads on types are order-dependent (first wins).
pybind/pybind11#1512

We specialize `double` here generically and cast in read if needed
(see #345 #1137).

Later on, we could add support for 1D numpy arrays with distinct
type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants