/*
Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
This file is part of CamCOPS.
CamCOPS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CamCOPS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <limits> // for std::numeric_limits
#include <new> // for std::bad_alloc
#include <QtGlobal> // for Q_UNUSED
// Currently unused.
template<typename T> struct zallocator
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
pointer address(reference v) const
{
return &v;
}
const_pointer address(const_reference v) const
{
return &v;
}
pointer allocate(size_type n, const void* hint = nullptr)
{
Q_UNUSED(hint)
if (n > std::numeric_limits<size_type>::max() / sizeof(T)) {
throw std::bad_alloc();
}
return static_cast<pointer>(::operator new(n * sizeof(value_type)));
}
void deallocate(pointer p, size_type n)
{
OPENSSL_cleanse(p, n * sizeof(T));
::operator delete(p);
}
size_type max_size() const
{
return std::numeric_limits<size_type>::max() / sizeof(T);
}
template<typename U> struct rebind
{
typedef zallocator<U> other;
};
void construct(pointer ptr, const T& val)
{
new (static_cast<T*>(ptr)) T(val);
}
void destroy(pointer ptr)
{
static_cast<T*>(ptr)->~T();
}
#if __cplusplus >= 201103L
template<typename U, typename... Args>
void construct(U* ptr, Args&&... args)
{
::new (static_cast<void*>(ptr)) U(std::forward<Args>(args)...);
}
template<typename U> void destroy(U* ptr)
{
ptr->~U();
}
#endif
};