Blob Blame Raw
#pragma once

#ifndef TCG_DELETER_TYPES_H
#define TCG_DELETER_TYPES_H

// tcg includes
#include "traits.h"

/*
  \file     deleter_types.h

  \brief    This file contains implementations of some useful deleter functors
            and deleter concepts.
*/

namespace tcg {

//*********************************************************************************
//    Deleter  objects
//*********************************************************************************

template <typename T>
struct deleter {
  void operator()(T *ptr) const { delete ptr; }
};

template <typename T>
struct deleter<T[]> {
  void operator()(T *ptr) const { delete[] ptr; }
};

template <typename T>
struct dtor {
  void operator()(T *ptr) const { ptr->~T(); }
};

template <typename T>
struct dtor<T[]> {
  int m_count;

  dtor(int count) : m_count(count) {}

  void operator()(T *ptr) const {
    for (int t = 0; t != m_count; ++t) ptr[t].~T();
  }
};

struct freer {
  void operator()(void *ptr) const { free(ptr); }
};

/*!
  The Deleter concept can be used to destroy instances of incomplete types.

  Deleter objects are useful in all cases where a type-erasure concept needs
  to support specialization on incomplete types.
*/

template <typename T>
class deleter_concept {
public:
  typedef typename tcg::traits<T>::pointer_type pointer_type;

public:
  virtual ~deleter_concept() {}

  virtual deleter_concept *clone() const    = 0;
  virtual void operator()(pointer_type ptr) = 0;
};

//--------------------------------------------------------------------------------

template <typename T>
class deleter_model : public deleter_concept<T> {
public:
  deleter_concept<T> *clone() const { return new deleter_model<T>(*this); }
  void operator()(T *ptr) { delete ptr; }
};

template <typename T>
class deleter_model<T[]> : public deleter_concept<T[]> {
public:
  deleter_concept<T[]> *clone() const { return new deleter_model<T[]>(*this); }
  void operator()(T *ptr) { delete[] ptr; }
};

}  // namespace tcg

#endif  // TCG_DELETER_TYPES_H