// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #ifndef JSON_ALLOCATOR_H_INCLUDED #define JSON_ALLOCATOR_H_INCLUDED #include <algorithm> #include <cstring> #include <memory> #pragma pack(push) #pragma pack() namespace Json { template <typename T> class SecureAllocator { public: // Type definitions using value_type = T; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using size_type = std::size_t; using difference_type = std::ptrdiff_t; /** * Allocate memory for N items using the standard allocator. */ pointer allocate(size_type n) { // allocate using "global operator new" return static_cast<pointer>(::operator new(n * sizeof(T))); } /** * Release memory which was allocated for N items at pointer P. * * The memory block is filled with zeroes before being released. */ void deallocate(pointer p, size_type n) { // These constructs will not be removed by the compiler during optimization, // unlike memset. #if defined(HAVE_MEMSET_S) memset_s(p, n * sizeof(T), 0, n * sizeof(T)); #elif defined(_WIN32) RtlSecureZeroMemory(p, n * sizeof(T)); #else std::fill_n(reinterpret_cast<volatile unsigned char*>(p), n, 0); #endif // free using "global operator delete" ::operator delete(p); } /** * Construct an item in-place at pointer P. */ template <typename... Args> void construct(pointer p, Args&&... args) { // construct using "placement new" and "perfect forwarding" ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...); } size_type max_size() const { return size_t(-1) / sizeof(T); } pointer address(reference x) const { return std::addressof(x); } const_pointer address(const_reference x) const { return std::addressof(x); } /** * Destroy an item in-place at pointer P. */ void destroy(pointer p) { // destroy using "explicit destructor" p->~T(); } // Boilerplate SecureAllocator() {} template <typename U> SecureAllocator(const SecureAllocator<U>&) {} template <typename U> struct rebind { using other = SecureAllocator<U>; }; }; template <typename T, typename U> bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) { return true; } template <typename T, typename U> bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) { return false; } } // namespace Json #pragma pack(pop) #endif // JSON_ALLOCATOR_H_INCLUDED