// -*- C++ -*-

// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option) any later
// version.

// This library 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.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.

// Permission to use, copy, modify, sell, and distribute this software
// is hereby granted without fee, provided that the above copyright
// notice appears in all copies, and that both that copyright notice
// and this permission notice appear in supporting documentation. None
// of the above authors, nor IBM Haifa Research Laboratories, make any
// representation about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

/**
 * @file ov_tree_map_.hpp
 * Contains an implementation class for ov_tree_.
 */

#include <map>
#include <set>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
#include <ext/pb_ds/detail/types_traits.hpp>
#include <ext/pb_ds/detail/debug_map_base.hpp>
#include <ext/pb_ds/detail/type_utils.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/detail/tree_trace_base.hpp>
#include <utility>
#include <functional>
#include <algorithm>
#include <vector>
#include <assert.h>
#include <debug/debug.h>

namespace __gnu_pbds
{
  namespace detail
  {
#define PB_DS_CLASS_T_DEC \
    template<typename Key, typename Mapped, class Cmp_Fn, \
	     class Node_And_It_Traits, class Allocator>

#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_OV_TREE_CLASS_NAME ov_tree_data_
#endif 

#ifdef PB_DS_DATA_FALSE_INDICATOR
#define PB_DS_OV_TREE_CLASS_NAME ov_tree_no_data_
#endif 

#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_
#else 
#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_
#endif 

#define PB_DS_CLASS_C_DEC \
   PB_DS_OV_TREE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator>

#define PB_DS_TYPES_TRAITS_C_DEC \
    types_traits<Key, Mapped, Allocator, false>

#ifdef _GLIBCXX_DEBUG
#define PB_DS_DEBUG_MAP_BASE_C_DEC \
    debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \
       	typename Allocator::template rebind<Key>::other::const_reference>
#endif 

#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_V2F(X) (X).first
#define PB_DS_V2S(X) (X).second
#define PB_DS_EP2VP(X)& ((X)->m_value)
#endif 

#ifdef PB_DS_DATA_FALSE_INDICATOR
#define PB_DS_V2F(X) (X)
#define PB_DS_V2S(X) Mapped_Data()
#define PB_DS_EP2VP(X)& ((X)->m_value.first)
#endif 

#ifdef PB_DS_TREE_TRACE
#define PB_DS_TREE_TRACE_BASE_C_DEC \
    tree_trace_base<typename Node_And_It_Traits::const_node_iterator, \
		    typename Node_And_It_Traits::node_iterator, \
		    Cmp_Fn, false, Allocator>
#endif 

    // Ordered-vector tree associative-container.
    template<typename Key, typename Mapped, class Cmp_Fn,
	     class Node_And_It_Traits, class Allocator>
    class PB_DS_OV_TREE_CLASS_NAME :
#ifdef _GLIBCXX_DEBUG
      protected PB_DS_DEBUG_MAP_BASE_C_DEC,
#endif 
#ifdef PB_DS_TREE_TRACE
      public PB_DS_TREE_TRACE_BASE_C_DEC,
#endif 
      public Cmp_Fn,
      public Node_And_It_Traits::node_update,
      public PB_DS_TYPES_TRAITS_C_DEC
    {
    private:
      typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;

      typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type;

      typedef typename Allocator::template rebind<non_const_value_type>::other value_allocator;
      typedef typename value_allocator::pointer value_vector;


      typedef Cmp_Fn cmp_fn_base;

#ifdef _GLIBCXX_DEBUG
      typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base;
#endif 

      typedef typename traits_base::pointer mapped_pointer_;
      typedef typename traits_base::const_pointer const_mapped_pointer_;

      typedef typename Node_And_It_Traits::metadata_type metadata_type;

      typedef typename Allocator::template rebind<metadata_type>::other metadata_allocator;
      typedef typename metadata_allocator::pointer metadata_pointer;
      typedef typename metadata_allocator::const_reference const_metadata_reference;
      typedef typename metadata_allocator::reference metadata_reference;

      typedef
      typename Node_And_It_Traits::null_node_update_pointer
      null_node_update_pointer;

    public:

      typedef Allocator allocator_type;
      typedef typename Allocator::size_type size_type;
      typedef typename Allocator::difference_type difference_type;

      typedef Cmp_Fn cmp_fn;

      typedef typename Node_And_It_Traits::node_update node_update;

      typedef typename traits_base::key_type key_type;
      typedef typename traits_base::key_pointer key_pointer;
      typedef typename traits_base::const_key_pointer const_key_pointer;
      typedef typename traits_base::key_reference key_reference;
      typedef typename traits_base::const_key_reference const_key_reference;
      typedef typename traits_base::mapped_type mapped_type;
      typedef typename traits_base::mapped_pointer mapped_pointer;
      typedef typename traits_base::const_mapped_pointer const_mapped_pointer;
      typedef typename traits_base::mapped_reference mapped_reference;
      typedef typename traits_base::const_mapped_reference const_mapped_reference;
      typedef typename traits_base::value_type value_type;
      typedef typename traits_base::pointer pointer;
      typedef typename traits_base::const_pointer const_pointer;
      typedef typename traits_base::reference reference;
      typedef typename traits_base::const_reference const_reference;

      typedef const_pointer const_point_iterator;

#ifdef PB_DS_DATA_TRUE_INDICATOR
      typedef pointer point_iterator;
#else 
      typedef const_point_iterator point_iterator;
#endif 

      typedef const_point_iterator const_iterator;

      typedef point_iterator iterator;

#include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp>

      typedef
      typename Node_And_It_Traits::const_node_iterator
      const_node_iterator;

      typedef typename Node_And_It_Traits::node_iterator node_iterator;

    public:

      PB_DS_OV_TREE_CLASS_NAME();

      PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&);

      PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&, const node_update&);

      PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC&);

      ~PB_DS_OV_TREE_CLASS_NAME();

      void
      swap(PB_DS_CLASS_C_DEC&);

      template<typename It>
      void
      copy_from_range(It, It);

      inline size_type
      max_size() const;

      inline bool
      empty() const;

      inline size_type
      size() const;

      Cmp_Fn& 
      get_cmp_fn();

      const Cmp_Fn& 
      get_cmp_fn() const;

      inline mapped_reference
      operator[](const_key_reference r_key)
      {
#ifdef PB_DS_DATA_TRUE_INDICATOR
	_GLIBCXX_DEBUG_ONLY(assert_valid();)
	point_iterator it = lower_bound(r_key);
	if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it)))
	  {
	    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key));
	    _GLIBCXX_DEBUG_ONLY(assert_valid();)
	     return it->second;
	  }

	_GLIBCXX_DEBUG_ONLY(assert_valid();)
	return (insert_new_val(it, std::make_pair(r_key, mapped_type()))->second);
#else 
	insert(r_key);
	return traits_base::s_null_mapped;
#endif 
      }

      inline std::pair<point_iterator, bool>
      insert(const_reference r_value)
      {
	_GLIBCXX_DEBUG_ONLY(assert_valid();)
	const_key_reference r_key = PB_DS_V2F(r_value);
	point_iterator it = lower_bound(r_key);

	if (it != end()&&  !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it)))
	  {
	    _GLIBCXX_DEBUG_ONLY(assert_valid();)
	    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key));
	    return std::make_pair(it, false);
	  }

	_GLIBCXX_DEBUG_ONLY(assert_valid();)
	return std::make_pair(insert_new_val(it, r_value), true);
      }

      inline point_iterator
      lower_bound(const_key_reference r_key)
      {
	pointer it = m_a_values;
	pointer e_it = m_a_values + m_size;
	while (it != e_it)
	  {
	    pointer mid_it = it + ((e_it - it) >> 1);
	    if (cmp_fn_base::operator()(PB_DS_V2F(*mid_it), r_key))
	      it = ++mid_it;
	    else
	      e_it = mid_it;
	  }
	return it;
      }

      inline const_point_iterator
      lower_bound(const_key_reference r_key) const
      { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); }

      inline point_iterator
      upper_bound(const_key_reference r_key)
      {
	iterator pot_it = lower_bound(r_key);
	if (pot_it != end()&&  !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it)))
	  {
	    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key));
	    return ++pot_it;
	  }

	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(r_key));
	return pot_it;
      }

      inline const_point_iterator
      upper_bound(const_key_reference r_key) const
      { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); }

      inline point_iterator
      find(const_key_reference r_key)
      {
	_GLIBCXX_DEBUG_ONLY(assert_valid();)
	iterator pot_it = lower_bound(r_key);
	if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it)))
	  {
	    _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(r_key));
	    return pot_it;
	  }

	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(r_key));
	return end();
      }

      inline const_point_iterator
      find(const_key_reference r_key) const
      { return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key)); }

      bool
      erase(const_key_reference);

      template<typename Pred>
      inline size_type
      erase_if(Pred);

      inline iterator
      erase(iterator it)
      { return erase_imp<iterator>(it); }

      void
      clear();

      void
      join(PB_DS_CLASS_C_DEC&);

      void
      split(const_key_reference, PB_DS_CLASS_C_DEC&);

      inline iterator
      begin()
      { return m_a_values; }

      inline const_iterator
      begin() const
      { return m_a_values; }

      inline iterator
      end()
      { return m_end_it; }

      inline const_iterator
      end() const
      { return m_end_it; }

      inline const_node_iterator
      node_begin() const;

      inline const_node_iterator
      node_end() const;

      inline node_iterator
      node_begin();

      inline node_iterator
      node_end();

    private:

      inline void
      update(node_iterator /*it*/, null_node_update_pointer);

      template<typename Node_Update>
      void
      update(node_iterator, Node_Update*);

      void
      reallocate_metadata(null_node_update_pointer, size_type);

      template<typename Node_Update_>
      void
      reallocate_metadata(Node_Update_*, size_type);

      template<typename It>
      void
      copy_from_ordered_range(It, It);

      void
      value_swap(PB_DS_CLASS_C_DEC&);

      template<typename It>
      void
      copy_from_ordered_range(It, It, It, It);

      template<typename Ptr>
      inline static Ptr
      mid_pointer(Ptr p_begin, Ptr p_end)
      {
	_GLIBCXX_DEBUG_ASSERT(p_end >= p_begin);
	return (p_begin + (p_end - p_begin) / 2);
      }

      inline iterator
      insert_new_val(iterator it, const_reference r_value)
      {
	_GLIBCXX_DEBUG_ONLY(assert_valid();)
#ifdef PB_DS_REGRESSION
	  typename Allocator::group_adjustor adjust(m_size);
#endif 

	_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(PB_DS_V2F(r_value)));

	value_vector a_values = s_value_alloc.allocate(m_size + 1);

	iterator source_it = begin();
	iterator source_end_it = end();
	iterator target_it = a_values;
	iterator ret_it;

	cond_dtor<size_type> cd(a_values, target_it, m_size + 1);
	while (source_it != it)
	  {
	    new (const_cast<void* >(static_cast<const void* >(target_it)))
	      value_type(*source_it++);
	    ++target_it;
	  }

	new (const_cast<void* >(static_cast<const void* >(ret_it = target_it)))
	  value_type(r_value);
	++target_it;

	while (source_it != source_end_it)
	  {
	    new (const_cast<void* >(static_cast<const void* >(target_it)))
	      value_type(*source_it++);
	    ++target_it;
	  }

	reallocate_metadata((node_update* )this, m_size + 1);
	cd.set_no_action();
	if (m_size != 0)
	  {
	    cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size);
	  }

	++m_size;
	m_a_values = a_values;
	m_end_it = m_a_values + m_size;
	_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value)));
	update(node_begin(), (node_update* )this);
	_GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();)
	return ret_it;
      }

#ifdef _GLIBCXX_DEBUG
      void
      assert_valid() const;

      void
      assert_iterators() const;
#endif 

      template<typename It>
      It
      erase_imp(It it);

      inline const_node_iterator
      PB_DS_node_begin_imp() const;

      inline const_node_iterator
      PB_DS_node_end_imp() const;

      inline node_iterator
      PB_DS_node_begin_imp();

      inline node_iterator
      PB_DS_node_end_imp();

    private:
      static value_allocator s_value_alloc;
      static metadata_allocator s_metadata_alloc;

      value_vector m_a_values;
      metadata_pointer m_a_metadata;
      iterator m_end_it;
      size_type m_size;
    };

#include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp>
#include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp>
#include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp>

#undef PB_DS_CLASS_C_DEC
#undef PB_DS_CLASS_T_DEC
#undef PB_DS_OV_TREE_CLASS_NAME
#undef PB_DS_TYPES_TRAITS_C_DEC
#undef PB_DS_DEBUG_MAP_BASE_C_DEC
#ifdef PB_DS_TREE_TRACE
#undef PB_DS_TREE_TRACE_BASE_C_DEC
#endif 

#undef PB_DS_V2F
#undef PB_DS_EP2VP
#undef PB_DS_V2S
#undef PB_DS_CONST_NODE_ITERATOR_NAME

  } // namespace detail
} // namespace __gnu_pbds
