This way, we won't need to reinvent the wheel of extern strings and extern arrays over and over again. Of course, it's up to user of such function to guarantee that pointer was allocated with provided allocator or compatible one.
template<typename T>
using MyVector = std::vector<T, MyCLibAllocator>;
...
CLibType* pArray = nullptr;
size_t nArray = 0;
CLib_obtainArray(&pArray, &nArray);
auto cLibVec = MyVector::from_raw_pointer(pArray, nArray, nArray);
My idea is to allow reuse of existing vector and string types, when buffer comes from external library.
On Fri, Oct 20, 2017 at 10:16 AM, Igor Baidiuk <targe...@gmail.com> wrote:My idea is to allow reuse of existing vector and string types, when buffer comes from external library.If a string comes from a different library, wrapping that in a std::basic_string won't work, becauses.push_back(0);will not do the right thing.
// clib_header.h
void* clib_allocate(size_t n);
void clib_deallocate(void*); // may be (void*, n), doesn't matter
struct clib_data { ... };
void clib_get_data(clib_data** p_data, size_t* n_data);
// clib_allocator.h
#include "clib_header.h"
template<typename T>
struct CLibAlloc
{
using value_type = T;
T* allocate(size_t n)
{
return (T*)clib_allocate(n * sizeof(T));
}
void deallocate(T* ptr, size_t)
{
clib_deallocate(ptr);
}
};
clib_data* p_data = nullptr;
size_t* n_data = 0;
clib_get_data(&p_data, &n_data);
auto datavec = std::vector::from_raw_pointer(p_data, n_data, n_data, CLibAlloc<clib_data>());
On 20 October 2017 at 19:33, Igor Baidiuk <targe...@gmail.com> wrote:
> Again. I'm not talking about any kind of allocator
> standartization/unification.
I am, however, suggesting that what you want to achieve needs two things:
a) a mallocator, because that's how most C libraries allocate
b) a means to transfer buffer ownership into and out of a vector, assuming that
the incoming buffer was allocated by a compatible allocator, and that the user
can know how to deallocate the outgoing buffer.
On Friday, 20 October 2017 09:50:32 PDT Nicol Bolas wrote:
> The other issue is how to deal with `basic_string` and its ability to use
> small-string optimization. That is, if I have a 12-byte string and I
> initialize an SSO `string` from it, when does my buffer get deleted? The
> `basic_string` should not be required to keep my buffer around if the
> number of characters fits into the SSO buffer. So we'd have to say that the
> buffer could be deleted as recently as the call that consumes it.
Right. Once you transfer ownership to the std type, it *owns* that buffer and
has the ability to free it as soon as it wants to.
using cstring = std::basic_string<char, mallocator>;
auto str = cstring::from_raw_string(someBuf, someLen);
if someLen < SSO threshold, one of two things can happen:
1) cstring points to your buffer, despite not needing to
2) cstring copies someBuf onto itself and frees your buffer using
the mallocator
Note, however, the consequence:
char *ptr = cstring.detach_buffer();
may fail.