/** \file
 * Defines the allocator interface as used by the KDTree class.
 *
 * \author Martin F. Krafft <libkdtree@pobox.madduck.net>
 */

#ifndef INCLUDE_KDTREE_ALLOCATOR_HPP
#define INCLUDE_KDTREE_ALLOCATOR_HPP

#include <cstddef>

#include "node.hpp"

namespace KDTree
{

  template<typename _Tp, typename _Alloc>
  class _Alloc_base {
  public:
    typedef _Node<_Tp> _Node_;
    typedef typename _Node_::_Base_ptr _Base_ptr;
    typedef _Alloc allocator_type;

    _Alloc_base(allocator_type const& __A) : _M_node_allocator(__A) {}

    allocator_type get_allocator() const { return _M_node_allocator; }


    class NoLeakAlloc {
      _Alloc_base* base;
      _Node_* new_node;

    public:
      NoLeakAlloc(_Alloc_base* b) : base(b), new_node(base->_M_allocate_node()) {}

      _Node_* get() { return new_node; }
      void disconnect() { new_node = NULL; }

      ~NoLeakAlloc()
      {
        if (new_node) base->_M_deallocate_node(new_node);
      }
    };


  protected:
    allocator_type _M_node_allocator;

    _Node_* _M_allocate_node() { return _M_node_allocator.allocate(1); }

    void _M_deallocate_node(_Node_* const __P) { return _M_node_allocator.deallocate(__P, 1); }

    void _M_construct_node(_Node_* __p, _Tp const __V = _Tp(), _Base_ptr const __PARENT = NULL,
                           _Base_ptr const __LEFT = NULL, _Base_ptr const __RIGHT = NULL)
    {
      new (__p) _Node_(__V, __PARENT, __LEFT, __RIGHT);
    }

    void _M_destroy_node(_Node_* __p) { _M_node_allocator.destroy(__p); }
  };

}  // namespace KDTree

#endif  // include guard

/* COPYRIGHT --
 *
 * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
 * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
 * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
 * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
 * root for more information.
 *
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
 * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */