#pragma once
#include "SafeList.h"
#include <boost/iterator/filter_iterator.hpp>

template <class T>
class ConstSafeListAdaptor
{
protected:
  struct NotDeleted
  {
    bool operator()(const typename SafeList<T>::Wrapper& wrapper) const
    {
      return !wrapper.isDeleted();
    }
  };
public:
  typedef boost::filter_iterator<NotDeleted, typename SafeList<T>::internal_const_iterator> const_iterator;

  ConstSafeListAdaptor(const SafeList<T>& safeList)
    : m_safeList(safeList)
  {
    //assert(safeList.m_nbCurrentIterations == 0);
  }
  const_iterator unsafe_begin() const { return const_iterator(NotDeleted(), m_safeList.m_list.begin(), m_safeList.m_list.end()); }
  const_iterator unsafe_end() const { return const_iterator(NotDeleted(), m_safeList.m_list.end(), m_safeList.m_list.end()); }

protected:
  const SafeList<T>& m_safeList;

private:
  //const member prevent the use of the assignment operator
  ConstSafeListAdaptor& operator= (const ConstSafeListAdaptor&);
};

template <class T>
class SafeListAdaptor : public ConstSafeListAdaptor<T>
{
public:
  typedef boost::filter_iterator<NotDeleted, typename SafeList<T>::internal_iterator> iterator;

  SafeListAdaptor(SafeList<T>& safeList)
    : ConstSafeListAdaptor(safeList)
    , m_safeList(safeList)
  {}
  iterator unsafe_begin() { return iterator(NotDeleted(), m_safeList.m_list.begin(), m_safeList.m_list.end()); }
  iterator unsafe_end() { return iterator(NotDeleted(), m_safeList.m_list.end(), m_safeList.m_list.end()); }

protected:
  SafeList<T>& m_safeList;
};