//
// Copyright (C) 2000-2002 Andrey Slepuhin <pooh@msu.ru>
//
// libp++ 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 2 of the License, or
// (at your option) any later version.
//
// libp++ 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 libp++; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// $Source$
// $Revision$
// $Date$
// Author: Andrey Slepuhin <pooh@msu.ru>

#ifndef __pxx_allocator_hh__
#define __pxx_allocator_hh__

#include "pxx_common.hh"
#include "pxx_sys_error.hh"

namespace pxx
{

#define ALLOCATOR_HAS_GET_REAL_SIZE             0x0001
#define ALLOCATOR_HAS_GET_BLOCK                 0x0002
#define ALLOCATOR_HAS_GET_BLOCK_WITH_SIZE       0x0004
#define ALLOCATOR_HAS_IS_DYN_ADDR               0x0008

extern bool default_allocator_destroyed ;

//
// Generic allocator interface
class Allocator
{

  friend class DefaultAllocator ;

private:

  bool set_as_default ;

protected:
  //
  // Allocator features
  unsigned features ;
  //
  NO_COPY_CTOR(Allocator)
  NO_ASSIGN(Allocator)

public:

  //
  // Constructor
  inline Allocator (unsigned _features = 0) ;
  //
  // Virtual destructor
  virtual inline ~Allocator () ;
  //
  // Allocate memory block of _size bytes
  virtual void* allocate (size_t _size) = 0 ;
  //
  // Free memory block at _ptr
  virtual void deallocate (void* _ptr) = 0 ;
  //
  // Resize memory block at _ptr to _size bytes
  virtual void* reallocate (void* _ptr, size_t _size) = 0 ;
  //
  // Returns (if possible) a real size (probably larger then given)
  // of memory block to be allocated
  virtual size_t get_real_size (size_t _size) const = 0 ;
  //
  // Returns (if possible) the start address of allocated block containing a
  // pointer, otherwise returns null
  virtual void* get_block (void* _ptr) = 0 ;
  //
  // The same as previous, but using block size
  virtual void* get_block (void* _ptr, size_t _size) = 0 ;
  //
  // Checks whether an address is in allocator address range
  virtual bool is_dyn_addr (void* _ptr) = 0 ;
  //
  // Get allocator features
  unsigned get_features () const { return features; }

};

}

#endif // __pxx_allocator_hh__

