Closed ujos closed 3 months ago
The intent was that data
doesn't return "usable" pointer if empty. Actually, in your case assertion is helpful because passing nullptr
to memcpy
is UB even if size is 0. You can just use dest.assign(std::begin(value), std::end(value))
which is clearer and shorter.
Also, it's not good to use types from detail
, they are implementation details. Let me know if there's no way you can avoid it and I'll think about making them public. For example here, can't you just do msg.dataField().assign(std::begin(str), std::end(str));
or at least use auto
for the first parameter?
Meanwhile, what is the proper way to initialize all the fields of the message? Is there a some kind of default constructor?
Nope, sbepp
generates a low-level wrapper that avoids doing anything beyond what's written explicitly. SBE doesn't have a notion of default values, the best we can do is to set null
values for optional top-level fields, initialize group
headers with 0 entries and data
fields to length 0
. Most of that you can achieve by filling your buffer with zeros. However, there are no good default values for required
fields, enum
s, set
s and composite
s so it's possible to have a really good "default constructor".
The intent was that data doesn't return "usable" pointer if empty. Actually, in your case assertion is helpful because passing nullptr to memcpy is UB even if size is 0. You can just use dest.assign(std::begin(value), std::end(value)) which is clearer and shorter.
In this case you can return a pointer right after the varLength
header. It is like an end pointer in the STL container.
Also, it's not good to use types from detail, they are implementation details. Let me know if there's no way you can avoid it and I'll think about making them public. For example here, can't you just do msg.dataField().assign(std::begin(str), std::end(str)); or at least use auto for the first parameter?
https://github.com/OleksandrKvl/sbepp/issues/24 :)
Nope, sbepp generates a low-level wrapper that avoids doing anything beyond what's written explicitly. SBE doesn't have a notion of default values, the best we can do is to set null values for optional top-level fields, initialize group headers with 0 entries and data fields to length 0. Most of that you can achieve by filling your buffer with zeros. However, there are no good default values for required fields, enums, sets and composites so it's possible to have a really good "default constructor".
Maybe it is not really a good idea to have a default constructor because of variable length fields...
In this case you can return a pointer right after the varLength header. It is like an end pointer in the STL container.
This has an overhead because dynamic_array_ref
is essentially a pointer, it can be nullptr
, in this case there's no way I can return "a pointer after varLength
". This would require an if-statement
which is not free. I need some time to think about it, maybe it really makes sense to remove !empty()
check and just say in documentation that in case size() == 0
, the returned pointer is not dereferenceable. Want to check how std::vector::data
behaves with debug iterators being enabled.
How it can be null? The header is always there, no? And the data is right after the header, as far as I remember.
dynamic_array_ref
has reference semantics, it only points to the memory in buffer where data
is stored. Default constructed dynamic_array_ref
holds nullptr
since it doesn't point anywhere.
--In this case you may want to see how string_view
is implemented--
Ah.. string_view
is a read only object. It may point on empty string. dynamic_array_ref
cannot point on some const static object, as one may want to change the size.
Yes, dynamic_array_ref
is closer to std::span
. I checked both libstdc++ and libc++, neither of them triggers assertion when data
is used on empty object so I will follow the same approach. Will make the change when I'll have free time.
Following is a body of the
dynamic_array_ref::data()
member function.As the first line of the code, there is a check for the emptiness. I'm not sure it should be there.
Consider the following code:
It is a proper code if you use for example
std::vector
instead ofdynamic_array_ref
. The issue is you cannot assign an empty string.Could you remove that check?
Meanwhile, what is the proper way to initialize all the fields of the message? Is there a some kind of default constructor?