Conversation
| | insert `item` into `vec` at index `9` | `type* temp = vector_insert_dst(&vec, type, 9);` | yes | No newline at end of file | ||
| | insert `item` into `vec` at index `9` | `type* temp = vector_insert_dst(&vec, type, 9);` | yes | |
There was a problem hiding this comment.
It seems you added or removed a trailing blank line. I don't think this is the desired change.
There was a problem hiding this comment.
Take another look at the full diff, please. I undid all the formatting changes you mentioned.
|
I like these changes from an API design perspective, but I have a few suggestions for their implementations. The main thing is that, as far as I know, each of the vector macros only ever evaluates the So my first suggestion would be to make helper functions for some of these. Here is an example for #define vector_end(vec) ((typeof(vec))_vector_end(vec, sizeof(*vec)))
vector _vector_end(vector vec, vec_type_t type_size)
{
return (vector)((unsigned char*)vec + (type_size * vector_size(vec)));
}The only major drawback I can see of doing it this way is that you would have to make a separate version for when It would be a bit more difficult to do this for // the (void*) is there because the declarator sequence removes all pointer info from the type,
// so (void*)item is just used to get a valid memory address that we can increment.
#define vector_foreach(item, vec) \
for (typeof(vec) _item = (vec), _end = vector_end(_item); _item != _end; ++_item) \
for (item = _item, *_loop_once = (void*)_item; (void*)_item == _loop_once; ++_loop_once)Maybe there's a much better way to do this, but it's a suggestion. Another solution to the "multiple evaluation" problem would be to add a section in the README warning about all of this, but I don't know if I like that solution as much. Thoughts? |
|
The joys of C macros! Thanks for your thoughtful reply. First, the initial PR I submitted had the unintentional formatting changes, and I meant to move the Regarding the double evaluation, your suggestion is the best standard workaround I can think of. I had to think about it for a minute, but One could use a statement expression: // Based on non-standard gcc statement expressions
#define vector_end(vec) ({typeof(vec) _vec = (vec); _vec + vector_size(_vec);})But that's another gcc extension, and I know it wouldn't be available in MSVC and others. Probably not a good idea for an open-source library! I'll take a longer look at your |
|
For the #if _MSC_VER != 0 && __STDC_VERSION__ < 202311L
#define typeof __typeof__
#endifBut this would have to be worked into the other preprocessor checks. I also think I have a much more robust version of the #define vector_foreach(item, vec) \
for (unsigned char* _item = (void*)(vec), *_end = (void*)vector_end((typeof(vec))_item), *_curr = _item; _item != _end; _curr = _item) \
for (item = (typeof(vec))_item; _curr == _item; _item += sizeof(*vec))The |
Nice library. I'm finding it very useful. I implemented some macros to make things a little more convenient, if you'd like to integrate them.