/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2011-2015  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM 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 3 of the License, or (at your option) any later version.
 *
 * ndnSIM 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
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#ifndef MULTI_POLICY_CONTAINER_H_
#define MULTI_POLICY_CONTAINER_H_

/// @cond include_hidden

#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/at.hpp>

namespace ns3 {
namespace ndn {
namespace ndnSIM {
namespace detail {

template<class Base, class Value>
struct policy_wrap {
  policy_wrap(Base& base)
    : value_(base)
  {
  }
  Value value_;
};

template<class Base, class Super /*empy_wrap/previous level*/,
         class Value /*policy_wrap< element in vector >*/>
struct inherit_with_base : Super, Value {
  inherit_with_base(Base& base)
    : Super(base)
    , Value(base)
  {
  }

  void
  update(typename Base::iterator item)
  {
    Value::value_.update(item);
    Super::update(item);
  }

  bool
  insert(typename Base::iterator item)
  {
    bool ok = Value::value_.insert(item);
    if (!ok)
      return false;

    ok = Super::insert(item);
    if (!ok) {
      Value::value_.erase(item);
      return false;
    }
    return true;
  }

  void
  lookup(typename Base::iterator item)
  {
    Value::value_.lookup(item);
    Super::lookup(item);
  }

  void
  erase(typename Base::iterator item)
  {
    Value::value_.erase(item);
    Super::erase(item);
  }

  void
  clear()
  {
    Value::value_.clear();
    Super::clear();
  }
};

template<class Base>
struct empty_policy_wrap {
  empty_policy_wrap(Base& base)
  {
  }

  void
  update(typename Base::iterator item)
  {
  }
  bool
  insert(typename Base::iterator item)
  {
    return true;
  }
  void
  lookup(typename Base::iterator item)
  {
  }
  void
  erase(typename Base::iterator item)
  {
  }
  void
  clear()
  {
  }
};

template<class Base, class Vector>
struct multi_policy_container
  : public boost::mpl::
      fold<Vector, empty_policy_wrap<Base>,
           inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                             policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type {
  typedef typename boost::mpl::
    fold<Vector, empty_policy_wrap<Base>,
         inherit_with_base<Base, boost::mpl::_1 /*empty/previous*/,
                           policy_wrap<Base, boost::mpl::_2> /*element in vector*/>>::type super;

  typedef typename boost::mpl::at_c<Vector, 0>::type::iterator iterator;
  typedef typename boost::mpl::at_c<Vector, 0>::type::const_iterator const_iterator;

  iterator
  begin()
  {
    return this->get<0>().begin();
  }
  const_iterator
  begin() const
  {
    return this->get<0>().begin();
  }

  iterator
  end()
  {
    return this->get<0>().end();
  }
  const_iterator
  end() const
  {
    return this->get<0>().end();
  }

  size_t
  size() const
  {
    return this->get<0>().size();
  }

  multi_policy_container(Base& base)
    : super(base)
  {
  }

  template<int N>
  struct index {
    typedef typename boost::mpl::at_c<Vector, N>::type type;
  };

  template<class T>
  T&
  get()
  {
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<class T>
  const T&
  get() const
  {
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  typename boost::mpl::at_c<Vector, N>::type&
  get()
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<policy_wrap<Base, T>&>(*this).value_;
  }

  template<int N>
  const typename boost::mpl::at_c<Vector, N>::type&
  get() const
  {
    typedef typename boost::mpl::at_c<Vector, N>::type T;
    return static_cast<const policy_wrap<Base, T>&>(*this).value_;
  }
};

} // detail
} // ndnSIM
} // ndn
} // ns3

/// @endcond

#endif // MULTI_POLICY_CONTAINER_H_
