Conversation
4a852ce to
5521d3e
Compare
5521d3e to
2845ab8
Compare
| #endif | ||
|
|
||
| template<typename T> T EndianSwap(T t) { | ||
| template<typename T> T EndianSwap(const T &t) { |
There was a problem hiding this comment.
This change worries me.. this function is meant for scalars only, and if any compiler anywhere compiles this more slowly than just T, we can't have it.
There was a problem hiding this comment.
With just T MSVC doesn't seem to propagate the __declspec(align()) attribute if I understand the issue correctly. Making it a const-ref bypasses this.
| } else if (sizeof(T) == 2) { | ||
| union { T t; uint16_t i; } u; | ||
| u.t = t; | ||
| union { T t; uint16_t i; } u = { t }; |
There was a problem hiding this comment.
Interesting.. making the assignment an initialization makes the error go away?
There was a problem hiding this comment.
Without this change MSVC reports: 'flatbuffers::EndianSwap::<unnamed-type-u>::<unnamed-type-u>(void)': attempting to reference a deleted function
Note EndianSwap is only used on big endian machines by EndianScalar, so I commented the #if FLATBUFFERS_LITTLEENDIAN to test it.
There was a problem hiding this comment.
Ok, but can we then make EndianScalar just T again? EndianSwap is fine since it is only ever used on big endian, but EndianScalar should be as obvious a no-op as possible for more naive compilers.
There was a problem hiding this comment.
Unfortunately the const-ref in WriteScalar is required otherwise C2719 't': formal parameter with requested alignment of 8 won't be aligned will persist, as the if-path will be evaluated even if it is not used.
There was a problem hiding this comment.
Agree with @vglavnyy, lets try the original plan then. EndianScalar (and to some extent WriteScalar) are such core functions in FlatBuffers, called absolutely everywhere, we can't afford the risk that this will regress performance on some compilers.
There was a problem hiding this comment.
There is another issue. The Get function uses ReadScalar via IndirectHelper. This of course will break on big endian machines. I thought about intorducing a GetStruct function, but then iterators and operator[] will be unusable in the current form.
There was a problem hiding this comment.
Why would that not work? IndirectHelper's 3rd case is for struct. It's the same code as for Vector which should work :)
There was a problem hiding this comment.
MSVC is probably weak when it comes to template specialization :(
I'm getting:
error C2719: 't': formal parameter with requested alignment of 8 won't be aligned
note: see reference to function template instantiation 'T flatbuffers::EndianScalar<T>(T)' being compiled
note: while compiling class template member function 'MyGame::Example::NestedStruct flatbuffers::IndirectHelper<T>::Read(const uint8_t *,flatbuffers::uoffset_t)'
note: see reference to function template instantiation 'MyGame::Example::NestedStruct flatbuffers::IndirectHelper<T>::Read(const uint8_t *,flatbuffers::uoffset_t)' being compiled`
note: see reference to class template instantiation 'flatbuffers::IndirectHelper<T>' being compiled
note: see reference to class template instantiation 'flatbuffers::Array<MyGame::Example::NestedStruct,2>' being compiled
There was a problem hiding this comment.
Probably, the best solution will be split Array class into two independent classes:
They have different iterators and Read/Write methods.
Array<T>- current implementation.ArrayOfStruct<S>- a new implementation.
|
I was probably too quick by going the cure the symptom not the disease route! EDIT: Seems like VS2013 does not like the solution. Probably we have to use GetMutablePointer or introduce MutateStruct. Alternatively we can inhibit the warning. |
|
@aardappel, @svenk177 I can make PR if this solution is fully acceptable. |
|
@vglavnyy This looks great. I thought about a similar solution, but was worried that the code will explode. Now that I look at it, it doesn't seem so bad :) |
|
It is possible to fold these three |
|
Yeah, it's a shame there's some duplication there, but if this is more solid, let's use @vglavnyy's implementation. |
|
@aardappel |
|
@vglavnyy I'd be fine with non-duplicated one as well, if it passes CI. But, in the end, your call, if the duplicated version is easier to use, that's ok too. |
…e#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods
…e#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods
* Draft with Array specialization (#5508) * Array specialization + SFINAE to fold copy-paste (#5508) * Add implicit specialization of Array<scalar> and Array<struct> (#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods * Add implicit specialization of Array<scalar> and Array<struct> (#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods
…5526) * Draft with Array specialization (google#5508) * Array specialization + SFINAE to fold copy-paste (google#5508) * Add implicit specialization of Array<scalar> and Array<struct> (google#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods * Add implicit specialization of Array<scalar> and Array<struct> (google#5508) - Tag dispatching is used for implicit specialization - Array<scalar> and Array<struct> have different iterators and accessors - Array<scalar> and Array<struct> have different Mutate() methods
This PR should (hopefully) fix the currently failing build on Visual Studio.
This got overlooked in my last PR (#5491), as the build job was never actually executed for some reason.