You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The main disadvantage of vector implementation with C-like access (that is, vec[i] instead of smth like vec_value( vec, i ) or vec->data[i]) is that we have to modify all the references on any vector operation that reallocates the underlying buffer. That could be not suitable for some cases.
There's a concept. To keep all the things unified, we can just add a data field into the vector header that will be NULL if vector is in the "mutable handles" mode (as now), and point to the data buffer otherwise.
Problems:
A set of functions obtaining the immutable handle type to operate on a vector will be reqired in a naive case, which is sucks (especially due to the nature of function instantiation). But it can be overcomed using the "reduced header" trick. That is, the data field in the header should be the last one. Thus, on every IGVEC_HEADER() we must go sizeof(void*) bytes back and examine the value. It it's NULL, then we're in the mutable mode so the header is up there. Otherwise, the examined value points to the header stored separately (which is the immutable handle), while the data field of the header itself points to the first element of the data (but not the actual buffer - its location is data - sizeof(void*)!). Thereby, we can operate on vectors using immutable handles just by passing immutable_handle->data (or &(immutable_handle->data) when required) to the same functions as used by regular mutable vectors, which is pretty cool.
By using another sizeof(void*) bytes of overhead we can go deeper and implement immutable headers that we'll can pass to functions just as mutable ones, i.e. without the ->data part. "Immutability costs", lol. But this is dirty from the point of view of types (it's better to have "immutable handle" as type alias of the type of header) and readability (easiness to mess up the mutable and the immutable handles). And how to access the actual vector data (particularly, its elements) in that case? However, in case of vec->data we can't access elements too because it's void*.
I should think of both implementations more thoroughly. Maybe it's better to have two different vector implementations at all (mutable / immutable)? But this is code duplication, and it sucks. But does anyone really need the mode switching feature?
Oh, a real trilemma of "speed / space / code beauty". :(
The main disadvantage of vector implementation with C-like access (that is,
vec[i]
instead of smth likevec_value( vec, i )
orvec->data[i]
) is that we have to modify all the references on any vector operation that reallocates the underlying buffer. That could be not suitable for some cases.There's a concept. To keep all the things unified, we can just add a
data
field into the vector header that will beNULL
if vector is in the "mutable handles" mode (as now), and point to the data buffer otherwise.Problems:
A set of functions obtaining the immutable handle type to operate on a vector will be reqired in a naive case, which is sucks (especially due to the nature of function instantiation). But it can be overcomed using the "reduced header" trick. That is, the
data
field in the header should be the last one. Thus, on everyIGVEC_HEADER()
we must gosizeof(void*)
bytes back and examine the value. It it'sNULL
, then we're in the mutable mode so the header is up there. Otherwise, the examined value points to the header stored separately (which is the immutable handle), while thedata
field of the header itself points to the first element of the data (but not the actual buffer - its location isdata - sizeof(void*)
!). Thereby, we can operate on vectors using immutable handles just by passingimmutable_handle->data
(or&(immutable_handle->data)
when required) to the same functions as used by regular mutable vectors, which is pretty cool.By using another
sizeof(void*)
bytes of overhead we can go deeper and implement immutable headers that we'll can pass to functions just as mutable ones, i.e. without the->data
part. "Immutability costs", lol. But this is dirty from the point of view of types (it's better to have "immutable handle" as type alias of the type of header) and readability (easiness to mess up the mutable and the immutable handles). And how to access the actual vector data (particularly, its elements) in that case? However, in case ofvec->data
we can't access elements too because it'svoid*
.I should think of both implementations more thoroughly. Maybe it's better to have two different vector implementations at all (mutable / immutable)? But this is code duplication, and it sucks. But does anyone really need the mode switching feature?
Oh, a real trilemma of "speed / space / code beauty". :(
On separating header from data and merging it back there we must note that
realloc()
doesn't guarantee in-place modification even if the size is less that it was:https://stackoverflow.com/questions/3162502/is-realloc-guaranteed-to-be-in-place-when-the-buffer-is-shrinking
All of this is closely related to #7.
The text was updated successfully, but these errors were encountered: