Background
I'm working with the Intel IPP Cryptographic Libraries for testing.
They define several opaque structs used for shared contexts over things like hashing and encryption which, of course, cannot be directly instantiated.
To initialize one of these opaque structs, you query for a byte size and then dynamically allocate some bytes and cast to the struct pointer.
Their examples work something like this:
int byteSize = 0;
ippsSHA256GetSize(&byteSize);
// IppsSHA256State shaCtx; // Error: incomplete type is not allowed
IppsSHA256State * shaCtx = (IppsSHA256State *)(new uint8_t[byteSize]);
// use shaCtx
delete [] (uint8_t *)shaCtx;
Question
What's the proper way to wrap this in a scoped pointer class so that I don't have to worry about deallocation?
Things I've Tried
I would think the following would not be safe since the call to delete in the destructor would be on the T type rather than a delete [] on the array that was actually allocated:
boost::scoped_ptr<IppsSHA256State> ctx(
reinterpret_cast<IppsSHA256State *>(new uint8_t[byteSize])
);
Another (simplified) option I've considered is a simple scoped pointer class of my own, but the casting there makes me unsure if this is correct, though my understanding of reinterpret_cast is that when cast back to the original type, there shouldn't be any ambiguity:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(reinterpret_cast<T *>(new uint8_t[byteSize]))
{}
T * get() const { return _ptr; }
~IppsScopedState(void) {
if (_ptr) delete [] reinterpret_cast<uint8_t *>(_ptr);
}
private:
T * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
Finally, I've considered a slight variation on the above:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(new uint8_t[byteSize])
{}
T * get() const { return reinterpret_cast<T *>(_ptr); }
~IppsScopedState(void) {
if (_ptr) delete [] _ptr;
}
private:
uint8_t * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
In either case, the usage would be like this:
IppsScopedState<IppsSHA256State> ctx(byteSize); // after querying for the byteSize, of course