[WIP] setAttribute with int/long on OSX & Win#333
Conversation
d426afc to
7f63290
Compare
|
I'm not yet fully grapsing the problem. using Attribute = Variant< T_dtype_enum, T_one, T_two, /* ... */ >;
T_two two = /* ... */;
Attribute(two).dtype == determineDatatype< T_two >();Which it probably does, but as Attribute(T_one()).dtype == Attribute(T_two()).dtypeis apparently true for some platforms and combinations, this might break the logic of correlating datatypes by simply looking up the enum position. Now to the problem at the pillar:
The core of this already exists as run-time behaviour in the form of template< class T_DTYPES, typename ... T >
class Variant
{
public:
using resource = variantSrc::variant< T ... >;
Variant(resource r)
: dtype{static_cast<T_DTYPES>(r.index())},
m_data{r}
{ }
} //Variantwe would have to explicitly cast the passed resource template< class T_DTYPES, typename ... T >
class Variant
{
public:
using resource = variantSrc::variant< T ... >;
template< typename U >
Variant(U&& u)
: dtype{determineDatatype< U >()},
m_data{resource(static_cast< YOUR_TRAIT< U >::type >(u))}
{ }
} //Variant |
|
@C0nsultant wrote to you on Gitter, we have a solution |
7f63290 to
115a836
Compare
ceff16b to
8ad30fb
Compare
|
|
||
| static_assert( | ||
| wasFound || value, | ||
| "Type was not found!" |
There was a problem hiding this comment.
Is this the compilation error one will get when doing something like
struct NotAnAttributeDType
{ };
Series s = /* ... */;
auto attr = NotAnAttributeDType();
s.setAttribute("nonsense", attr);?
There was a problem hiding this comment.
Yes, e.g. on GCC 6.3 you get (I removed the c-string handling for demonstration):
openPMD-api/include/openPMD/backend/Attribute.hpp:97:9:
error: static assertion failed: Type was not found!
static_assert(
^~~~~~~~~~~~~
In file included from openPMD-api/include/openPMD/Iteration.hpp:23:0,
from openPMD-api/include/openPMD/openPMD.hpp:27,
from openPMD-api/test/SerialIOTest.cpp:8:
openPMD-api/include/openPMD/backend/Attributable.hpp: In instantiation of ‘bool openPMD::Attributable::setAttribute(const string&, const T&) [with T = char [59]; std::__cxx11::string = std::__cxx11::basic_string<char>]’:
openPMD-api/test/SerialIOTest.cpp:1290:80: required from here
openPMD-api/include/openPMD/backend/Attributable.hpp:234:32: warning: the compiler can assume that the address of ‘value’ will always evaluate to ‘true’ [-Waddress]
it->second = Attribute(static_cast<FixedSize const&>(value));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
openPMD-api/include/openPMD/backend/Attributable.hpp:240:66: warning: the compiler can assume that the address of ‘value’ will always evaluate to ‘true’ [-Waddress]
std::make_pair(key, Attribute(static_cast<FixedSize const&>(value))));
| * Takes a fundamental type in T_Input and converts it to its fixed size equivalent. | ||
| * T_Input is compared against all supported types in @see Attribute . | ||
| * | ||
| * Returns the original type of T_Input is already a fixed size type. |
There was a problem hiding this comment.
Typo?
the original type if T_Input
| s.setAttribute("vecLong", std::vector< long >({2147483646, 2147483647})); | ||
| s.setAttribute("vecUShort", std::vector< unsigned short >({65534u, 65535u})); | ||
| s.setAttribute("vecUInt", std::vector< unsigned int >({65533u, 65531u})); | ||
| s.setAttribute("vecULong", std::vector< unsigned long >({65532u, 65530u})); |
There was a problem hiding this comment.
There already is a testcase in CoreTest.cpp that does similar checks. As this is (probably?) not supposed to check the workings in the backend, and rather in Attribute, the tests are better suited there.
There was a problem hiding this comment.
Ah dang, no... I moved the test to CoreTest now where a (non-user typical) Attribute() is created directly. I did not fix that yet (see reason below). I fixed the user-interface setAttribute.
8ad30fb to
5000d12
Compare
|
thx for the review, addressed all points. Will push the other commits after the test has failed, so I see if the issue is still visible as intended. |
test/CoreTest.cpp
Outdated
| // translation from non-fixed size integer types | ||
| a = Attribute(static_cast< short >(1)); | ||
| REQUIRE(( | ||
| Datatype::INT16 == a.dtype || Datatype::INT32 == a.dtype || Datatype::INT64 == a.dtype |
There was a problem hiding this comment.
determineDatatype() provides the datatype of explicit fixed width you are looking for. Would be a little easier to read and more explicit.
a = Attribute(static_cast< short >(1));
REQUIRE(determineDatatype< short >() == a.dtype);There was a problem hiding this comment.
Sounds legit, but wouldn't we then test determineDatatype() only against itself?
Anyway, the real test this adds is about the line above, if it compiles:
a = Attribute(static_cast< short >(1));
I just added the REQUIRE line as well for consistency with the existing checks.
There was a problem hiding this comment.
wouldn't we then test determineDatatype() only against itself?
No, because Attribute.datatype is not determined by determineDatatype(), but by (std::/mpark::)Variant with a subsequent lookup in the Datatype enum.
|
@C0nsultant a note on your proposal here: I would like to move the trait into the Since this will be a larger refactoring, e.g. unifying |
|
@C0nsultant will have to push once more. The test needs to go into |
test/CoreTest.cpp
Outdated
| REQUIRE(Datatype::BOOL == a.dtype); | ||
|
|
||
| /* translation from non-fixed size integer types | ||
| * @todo see |
There was a problem hiding this comment.
@C0nsultant I will leave this prepared test in here, for #333
206e09a to
d9b81f7
Compare
| template<bool wasFound, typename U, typename T_Head, typename ...T> | ||
| struct FindTypeImpl | ||
| { | ||
| static constexpr bool value = std::is_same< |
There was a problem hiding this comment.
hm, on the platforms with trouble, is_same will still return false although they are the same... Argh!
There was a problem hiding this comment.
turns out they are not the same. each of them are distinct types, just some happen to implement the same precision. int32_t and others are typedef aliases of the funnily named ones (short, int) but not vice versa and not across the latter.
|
Regarding our underlying issue, this might be interesting reads: One could now probably either follow this and go for the fundamental types instead of fixed-size types in all relevant comparisons (e.g. all four It's also interesting to see that our variadic templates in |
d9b81f7 to
cb95c26
Compare
| s.setAttribute("vecLong", std::vector< long >({2147483646, 2147483647})); | ||
| s.setAttribute("vecUShort", std::vector< unsigned short >({65534u, 65535u})); | ||
| s.setAttribute("vecUInt", std::vector< unsigned int >({65533u, 65531u})); | ||
| s.setAttribute("vecULong", std::vector< unsigned long >({65532u, 65530u})); |
There was a problem hiding this comment.
read: getAttribute check missing
Fix access to local `detail` namespace.
Explicitly handle C-strings in order to avoid implicit casts. Makes bindings easier.
Test HDF5/ADIOS1 of writing and reading attributes with non-fixed size types.
cb95c26 to
6a77f2e
Compare
|
This PR is mainly solved with #337. I will re-open what is left in here (increased coverage, maybe unique C-string signature for set-attribute, maybe the scope fix in one of the tests) into separate PRs. |
| * @param value Value of Attribute stored with the provided key. | ||
| * @return true if key was already present, false otherwise | ||
| * | ||
| * @{ |
There was a problem hiding this comment.
Out of curiosity:
I am unfamiliar with this systax. Does this tell doxygen to generate only one doc for the both of these?
There was a problem hiding this comment.
Yes, exactly. It's doxyen group-ing for exactly that use case :)
| s.setAttribute("vecLongdouble", std::vector< long double >({0.L, std::numeric_limits<long double>::max()})); | ||
| s.setAttribute("vecString", std::vector< std::string >({"vector", "of", "strings"})); | ||
| s.setAttribute("bool", static_cast< unsigned char >(true)); | ||
| // s.setAttribute("bool", true); |
There was a problem hiding this comment.
See #337 (comment) in review comment #337 (review) (not uncollapsed when using direct link).
| #endif | ||
| REQUIRE(s.getAttribute("vecString").get< std::vector< std::string > >() == std::vector< std::string >({"vector", "of", "strings"})); | ||
| REQUIRE(s.getAttribute("bool").get< unsigned char >() == static_cast< unsigned char >(true)); | ||
| // REQUIRE(s.getAttribute("bool").get< bool >() == true); |
There was a problem hiding this comment.
See #337 (comment) in review comment #337 (review) (not uncollapsed when using direct link).
|
@C0nsultant I will rip this PR apart, since it's otherwise too confusing (#333 (comment)) |
Test that writing attributes with non-fixed size types works.
Seems to crash on some environments, such as:
longislong longlongandintare identicalProblem is, that only one of them is in the variant list and it seems automatic detection that they are the same is not performed in
varianton the two obscure OSes above. We should therefore write a trait, that converts types such asintto their current, platform-specific fixed-size type during access, e.g. inAttributablewhereAttribute(value)is called.Or in simple words: on OSX and with MSVC on Windows this did not compile:
since
Attribute(value)complains that ourVariantdoes not containlong(but e.g. onlyintandlong longalthoughintis equivalent tolong).First seen here.