// 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 <cstring>
#include <memory>

#if !defined(__SUNPRO_CC)
#pragma pack(push, 8)
#endif

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.
   * The pointer argument is tagged as "volatile" to prevent the
   * compiler optimizing out this critical step.
   */
  void deallocate(volatile pointer p, size_type n) {
    std::memset(p, 0, n * sizeof(T));
    // 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

#if !defined(__SUNPRO_CC)
#pragma pack(pop)
#endif

#endif // JSON_ALLOCATOR_H_INCLUDED
