//  (C) Copyright Jeremy Siek 2004 
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
#define BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H

// Sure would be nice to be able to forward declare these
// instead of pulling in all the headers. Too bad that
// is not legal. There ought to be a standard <stlfwd> header. -JGS 

#include <boost/next_prior.hpp>

#include <algorithm>   // for std::remove
#include <vector>
#include <list>
#include <map>
#include <set>

#if !defined BOOST_NO_HASH
#  ifdef BOOST_HASH_SET_HEADER
#    include BOOST_HASH_SET_HEADER
#  else
#    include <hash_set>
#  endif
#  ifdef BOOST_HASH_MAP_HEADER
#    include BOOST_HASH_MAP_HEADER
#  else
#    include <hash_map>
#  endif
#endif

#if !defined BOOST_NO_SLIST
#  ifdef BOOST_SLIST_HEADER
#    include BOOST_SLIST_HEADER
#  else
#    include <slist>
#  endif
#endif

#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Stay out of the way of concept checking class templates
# define Container Container_
# define AssociativeContainer AssociativeContainer_
#endif

// The content of this file is in 'graph_detail' because otherwise
// there will be name clashes with 
// sandbox/boost/sequence_algo/container_traits.hpp
// The 'detail' subnamespace will still cause problems.
namespace boost { namespace graph_detail {

  //======================================================================
  // Container Category Tags
  //
  //   They use virtual inheritance because there are lots of
  //   inheritance diamonds.

  struct container_tag { };
  struct forward_container_tag : virtual public container_tag { };
  struct reversible_container_tag : virtual public forward_container_tag { };
  struct random_access_container_tag
    : virtual public reversible_container_tag { };
  
  struct sequence_tag : virtual public forward_container_tag { };

  struct associative_container_tag : virtual public forward_container_tag { };

  struct sorted_associative_container_tag 
    : virtual public associative_container_tag,
      virtual public reversible_container_tag { };

  struct front_insertion_sequence_tag : virtual public sequence_tag { };
  struct back_insertion_sequence_tag : virtual public sequence_tag { };

  struct unique_associative_container_tag 
    : virtual public associative_container_tag { };
  struct multiple_associative_container_tag 
    : virtual public associative_container_tag { };
  struct simple_associative_container_tag 
    : virtual public associative_container_tag { };
  struct pair_associative_container_tag 
    : virtual public associative_container_tag { };


  //======================================================================
  // Iterator Stability Tags
  //
  // Do mutating operations such as insert/erase/resize invalidate all
  // outstanding iterators?

  struct stable_tag { };
  struct unstable_tag { };

  //======================================================================
  // Container Traits Class and container_category() function

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  // don't use this unless there is partial specialization 
  template <class Container>
  struct container_traits {
    typedef typename Container::category category;
    typedef typename Container::iterator_stability iterator_stability;
  };
#endif

  // Use this as a compile-time assertion that X is stable
  inline void require_stable(stable_tag) { }

  // std::vector
  struct vector_tag :
    virtual public random_access_container_tag,
    virtual public back_insertion_sequence_tag { };

  template <class T, class Alloc>
  vector_tag container_category(const std::vector<T,Alloc>&)
    { return vector_tag(); }

  template <class T, class Alloc>
  unstable_tag iterator_stability(const std::vector<T,Alloc>&)
    { return unstable_tag(); }

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, class Alloc>
  struct container_traits< std::vector<T,Alloc> > {
    typedef vector_tag category;
    typedef unstable_tag iterator_stability;
  };
#endif

  // std::list
  struct list_tag :
    virtual public reversible_container_tag,
    virtual public back_insertion_sequence_tag
    // this causes problems for push_dispatch...
    //    virtual public front_insertion_sequence_tag
    { };

  template <class T, class Alloc>
  list_tag container_category(const std::list<T,Alloc>&)
    { return list_tag(); }

  template <class T, class Alloc>
  stable_tag iterator_stability(const std::list<T,Alloc>&)
    { return stable_tag(); }

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, class Alloc>
  struct container_traits< std::list<T,Alloc> > {
    typedef list_tag category;
    typedef stable_tag iterator_stability;
  };
#endif


  // std::slist
#ifndef BOOST_NO_SLIST
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, class Alloc>
  struct container_traits<BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc> > {
    typedef front_insertion_sequence_tag category;
    typedef stable_tag iterator_stability;
  };
#endif
  template <class T, class Alloc>
  front_insertion_sequence_tag container_category(
  const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&
  )
    { return front_insertion_sequence_tag(); }

  template <class T, class Alloc>
  stable_tag iterator_stability(
  const BOOST_STD_EXTENSION_NAMESPACE::slist<T,Alloc>&)
    { return stable_tag(); }
#endif


  // std::set
  struct set_tag :
    virtual public sorted_associative_container_tag,
    virtual public simple_associative_container_tag,
    virtual public unique_associative_container_tag 
    { };

  template <class Key, class Cmp, class Alloc> 
  set_tag container_category(const std::set<Key,Cmp,Alloc>&)
  { return set_tag(); }

  template <class Key, class Cmp, class Alloc> 
  stable_tag iterator_stability(const std::set<Key,Cmp,Alloc>&)
  { return stable_tag(); }

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class Key, class Cmp, class Alloc> 
  struct container_traits< std::set<Key,Cmp,Alloc> > {
    typedef set_tag category;
    typedef stable_tag iterator_stability;
  };
#endif

  // std::multiset
  struct multiset_tag :
    virtual public sorted_associative_container_tag,
    virtual public simple_associative_container_tag,
    virtual public multiple_associative_container_tag 
    { };

  template <class Key, class Cmp, class Alloc> 
  multiset_tag container_category(const std::multiset<Key,Cmp,Alloc>&)
  { return multiset_tag(); }

  template <class Key, class Cmp, class Alloc> 
  stable_tag iterator_stability(const std::multiset<Key,Cmp,Alloc>&)
  { return stable_tag(); }

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class Key, class Cmp, class Alloc> 
  struct container_traits< std::multiset<Key,Cmp,Alloc> > {
    typedef multiset_tag category;
    typedef stable_tag iterator_stability;
  };
#endif

  // deque

  // std::map
  struct map_tag :
    virtual public sorted_associative_container_tag,
    virtual public pair_associative_container_tag,
    virtual public unique_associative_container_tag 
    { };

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class Key, class T, class Cmp, class Alloc> 
  struct container_traits< std::map<Key,T,Cmp,Alloc> > {
    typedef map_tag category;
    typedef stable_tag iterator_stability;
  };
#endif

  template <class Key, class T, class Cmp, class Alloc> 
  map_tag container_category(const std::map<Key,T,Cmp,Alloc>&)
  { return map_tag(); }

  template <class Key, class T, class Cmp, class Alloc> 
  stable_tag iterator_stability(const std::map<Key,T,Cmp,Alloc>&)
  { return stable_tag(); }

  // std::multimap
  struct multimap_tag :
    virtual public sorted_associative_container_tag,
    virtual public pair_associative_container_tag,
    virtual public multiple_associative_container_tag 
    { };

#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class Key, class T, class Cmp, class Alloc> 
  struct container_traits< std::multimap<Key,T,Cmp,Alloc> > {
    typedef multimap_tag category;
    typedef stable_tag iterator_stability;
  };
#endif

  template <class Key, class T, class Cmp, class Alloc> 
  multimap_tag container_category(const std::multimap<Key,T,Cmp,Alloc>&)
  { return multimap_tag(); }

  template <class Key, class T, class Cmp, class Alloc> 
  stable_tag iterator_stability(const std::multimap<Key,T,Cmp,Alloc>&)
  { return stable_tag(); }


 // hash_set, hash_map

#ifndef BOOST_NO_HASH
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class Key, class Eq, class Hash, class Alloc> 
  struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc> > {
    typedef set_tag category;
    typedef stable_tag iterator_stability; // is this right?
  };
  template <class Key, class T, class Eq, class Hash, class Alloc>
  struct container_traits< BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc> > {
    typedef map_tag category;
    typedef stable_tag iterator_stability; // is this right?
  };
#endif
  template <class Key, class Eq, class Hash, class Alloc>
  set_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc>&)
  { return set_tag(); }

  template <class Key, class T, class Eq, class Hash, class Alloc>
  map_tag container_category(const BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc>&)
  { return map_tag(); }

  template <class Key, class Eq, class Hash, class Alloc>
  stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_set<Key,Eq,Hash,Alloc>&)
  { return stable_tag(); }

  template <class Key, class T, class Eq, class Hash, class Alloc>
  stable_tag iterator_stability(const BOOST_STD_EXTENSION_NAMESPACE::hash_map<Key,T,Eq,Hash,Alloc>&)
  { return stable_tag(); }
#endif



  //===========================================================================
  // Generalized Container Functions


  // Erase
  template <class Sequence, class T>
  void erase_dispatch(Sequence& c, const T& x, 
                      sequence_tag)
  {
    c.erase(std::remove(c.begin(), c.end(), x), c.end());
  }

  template <class AssociativeContainer, class T>
  void erase_dispatch(AssociativeContainer& c, const T& x, 
                      associative_container_tag)
  {
    c.erase(x);
  }
  template <class Container, class T>
  void erase(Container& c, const T& x)
  {
    erase_dispatch(c, x, container_category(c));
  }

  // Erase If
  template <class Sequence, class Predicate, class IteratorStability>
  void erase_if_dispatch(Sequence& c, Predicate p,
                         sequence_tag, IteratorStability)
  {
#if 0
    c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
#else
    if (! c.empty())
      c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
#endif
  }
  template <class AssociativeContainer, class Predicate>
  void erase_if_dispatch(AssociativeContainer& c, Predicate p,
                         associative_container_tag, stable_tag)
  {
    typename AssociativeContainer::iterator i, next;
    for (i = next = c.begin(); next != c.end(); i = next) {
      ++next;
      if (p(*i))
        c.erase(i);
    }
  }
  template <class AssociativeContainer, class Predicate>
  void erase_if_dispatch(AssociativeContainer& c, Predicate p,
                         associative_container_tag, unstable_tag)
  {
    // This method is really slow, so hopefully we won't have any
    // associative containers with unstable iterators!
    // Is there a better way to do this?
    typename AssociativeContainer::iterator i;
    typename AssociativeContainer::size_type n = c.size();
    while (n--)
      for (i = c.begin(); i != c.end(); ++i)
        if (p(*i)) {
          c.erase(i);
          break;
        }
  }
  template <class Container, class Predicate>
  void erase_if(Container& c, Predicate p)
  {
    erase_if_dispatch(c, p, container_category(c), iterator_stability(c));
  }

  // Push
  template <class Container, class T>
  std::pair<typename Container::iterator, bool>
  push_dispatch(Container& c, const T& v, back_insertion_sequence_tag)
  {
    c.push_back(v);
    return std::make_pair(boost::prior(c.end()), true);
  }

  template <class Container, class T>
  std::pair<typename Container::iterator, bool>
  push_dispatch(Container& c, const T& v, front_insertion_sequence_tag)
  {
    c.push_front(v);
    return std::make_pair(c.begin(), true);
  }

  template <class AssociativeContainer, class T>
  std::pair<typename AssociativeContainer::iterator, bool>
  push_dispatch(AssociativeContainer& c, const T& v, 
                unique_associative_container_tag)
  {
    return c.insert(v);
  }

  template <class AssociativeContainer, class T>
  std::pair<typename AssociativeContainer::iterator, bool>
  push_dispatch(AssociativeContainer& c, const T& v,
                multiple_associative_container_tag)
  {
    return std::make_pair(c.insert(v), true);
  }

  template <class Container, class T>
  std::pair<typename Container::iterator,bool>
  push(Container& c, const T& v)
  {
    return push_dispatch(c, v, container_category(c));
  }

}} // namespace boost::graph_detail

#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Stay out of the way of concept checking class templates
# undef Container
# undef AssociativeContainer
#endif

#endif // BOOST_GRAPH_DETAIL_CONTAINER_TRAITS_H
