/* Copyright (c) 1997-2006
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program 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, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program 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.
*/

#ifndef _POLYMAKE_TREE_CONTAINERS_H
#define _POLYMAKE_TREE_CONTAINERS_H "$Project: polymake $$Id: tree_containers.h 7402 2006-07-27 23:44:14Z gawrilow $"

#ifndef _POLYMAKE_ITERATORS_H
#  include <iterators.h>
#endif

namespace pm {

template <typename Top, typename Params=typename Top::manipulator_params>
class modified_tree
   : public modified_container_impl<Top,Params> {
   typedef modified_container_impl<Top, Params> _super;
public:
   typedef typename _super::container::tree_type tree_type;
   typedef typename _super::iterator iterator;
   typedef typename _super::const_iterator const_iterator;

   template <typename Key>
   iterator find(const Key& k)
   {
      return iterator(this->top().get_container().find(k), this->top().get_operation());
   }
   template <typename Key>
   const_iterator find(const Key& k) const
   {
      return const_iterator(this->top().get_container().find(k), this->top().get_operation());
   }
   template <typename Key, typename Comparator>
   iterator find(const Key& k, const Comparator& comparator)
   {
      return iterator(this->top().get_container().find(k,comparator), this->top().get_operation());
   }
   template <typename Key, typename Comparator>
   const_iterator find(const Key& k, const Comparator& comparator) const
   {
      return const_iterator(this->top().get_container().find(k,comparator), this->top().get_operation());
   }

   template <typename Key, typename RelOp>
   iterator find_nearest(const Key& k, const RelOp& relop)
   {
      return iterator(this->top().get_container().find_nearest(k,relop), this->top().get_operation());
   }
   template <typename Key, typename RelOp>
   const_iterator find_nearest(const Key& k, const RelOp& relop) const
   {
      return const_iterator(this->top().get_container().find_nearest(k,relop), this->top().get_operation());
   }
   template <typename Key, typename RelOp, typename Comparator>
   iterator find_nearest(const Key& k, const RelOp& relop, const Comparator& comparator)
   {
      return iterator(this->top().get_container().find_nearest(k,relop,comparator), this->top().get_operation());
   }
   template <typename Key, typename RelOp, typename Comparator>
   const_iterator find_nearest(const Key& k, const RelOp& relop, const Comparator& comparator) const
   {
      return const_iterator(this->top().get_container().find_nearest(k,relop,comparator), this->top().get_operation());
   }

   template <typename Key>
   bool exists(const Key& k) const
   {
      return this->top().get_container().exists(k);
   }

   // synonym for sets
   template <typename Key>
   bool contains(const Key& k) const { return exists(k); }

   template <typename First>
   iterator insert(const First& first_arg)
   {
      return iterator(this->top().get_container().insert(first_arg), this->top().get_operation());
   }
   template <typename First, typename Second>
   iterator insert(const First& first_arg, const Second& second_arg)
   {
      return iterator(this->top().get_container().insert(first_arg,second_arg), this->top().get_operation());
   }
   template <typename First, typename Second, typename Third>
   iterator insert(const First& first_arg, const Second& second_arg, const Third& third_arg)
   {
      return iterator(this->top().get_container().insert(first_arg,second_arg,third_arg), this->top().get_operation());
   }

   template <typename Key_or_Iterator>
   void erase(const Key_or_Iterator& k_or_it)
   {
      this->top().get_container().erase(k_or_it);
   }

   template <typename Key>
   iterator toggle(const Key& k)
   {
      return iterator(this->top().get_container().toggle(k), this->top().get_operation());
   }

   template <typename Key>
   void push_front(const Key& k)
   {
      this->top().get_container().push_front(k);
   }
   template <typename Key, typename Data>
   void push_front(const Key& k, const Data& data)
   {
      this->top().get_container().push_front(k,data);
   }

   template <typename Key>
   void push_back(const Key& k)
   {
      this->top().get_container().push_back(k);
   }
   template <typename Key, typename Data>
   void push_back(const Key& k, const Data& data)
   {
      this->top().get_container().push_back(k,data);
   }
   void pop_front()
   {
      this->top().get_container().pop_front();
   }
   void pop_back()
   {
      this->top().get_container().pop_back();
   }

   bool tree_form() const
   {
      return this->top().get_container().tree_form();
   }
   int max_size() const
   {
      return this->top().get_container().max_size();
   }
   void clear()
   {
      this->top().get_container().clear();
   }

   const typename tree_type::key_comparator_type&
   get_comparator_object() const
   {
      return this->top().get_container().get_comparator_object();
   }
};

} // end namespace pm

#endif // _POLYMAKE_TREE_CONTAINERS_H

// Local Variables:
// mode:C++
// End:
