// -*- C++ -*-

// Copyright (C) 2005-2013 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_/ov_tree_map_.hpp
 * Contains an implementation class for ov_tree.
 */

#include <map>
#include <set>
#include <ext/pb_ds/exception.hpp>
#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/type_utils.hpp>
#include <ext/pb_ds/detail/tree_trace_base.hpp>
#ifdef _GLIBCXX_DEBUG
#include <ext/pb_ds/detail/debug_map_base.hpp>
#endif
#include <utility>
#include <functional>
#include <algorithm>
#include <vector>
#include <assert.h>
#include <debug/debug.h>

namespace __gnu_pbds
{
  namespace detail
  {
#ifdef PB_DS_DATA_TRUE_INDICATOR
#define PB_DS_OV_TREE_NAME ov_tree_map
#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_map
#endif

#ifdef PB_DS_DATA_FALSE_INDICATOR
#define PB_DS_OV_TREE_NAME ov_tree_set
#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_set
#endif

#define PB_DS_CLASS_T_DEC \
    template<typename Key, typename Mapped, typename Cmp_Fn, \
	     typename Node_And_It_Traits, typename _Alloc>

#define PB_DS_CLASS_C_DEC \
   PB_DS_OV_TREE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc>

#define PB_DS_OV_TREE_TRAITS_BASE \
    types_traits<Key, Mapped, _Alloc, false>

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

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

#ifndef PB_DS_CHECK_KEY_EXISTS
#  error Missing definition
#endif

    /**
     *  @brief Ordered-vector tree associative-container.
     *  @ingroup branch-detail
     */
    template<typename Key, typename Mapped, typename Cmp_Fn,
	     typename Node_And_It_Traits, typename _Alloc>
    class PB_DS_OV_TREE_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_OV_TREE_TRAITS_BASE
    {
    private:
      typedef PB_DS_OV_TREE_TRAITS_BASE	       		traits_base;
      typedef Node_And_It_Traits			traits_type;

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

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

#ifdef _GLIBCXX_DEBUG
      typedef PB_DS_DEBUG_MAP_BASE_C_DEC 		debug_base;
#endif

#ifdef PB_DS_TREE_TRACE
      typedef PB_DS_TREE_TRACE_BASE_C_DEC 		trace_base;
#endif

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

      typedef typename traits_type::metadata_type 	metadata_type;

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

      typedef typename traits_type::null_node_update_pointer
      null_node_update_pointer;

    public:
      typedef ov_tree_tag 				 container_category;
      typedef _Alloc 					allocator_type;
      typedef typename _Alloc::size_type 		size_type;
      typedef typename _Alloc::difference_type 		difference_type;
      typedef Cmp_Fn 					cmp_fn;

      typedef typename traits_base::key_type 		key_type;
      typedef typename traits_base::key_pointer 	key_pointer;
      typedef typename traits_base::key_const_pointer 	key_const_pointer;
      typedef typename traits_base::key_reference 	key_reference;
      typedef typename traits_base::key_const_reference key_const_reference;
      typedef typename traits_base::mapped_type 	mapped_type;
      typedef typename traits_base::mapped_pointer 	mapped_pointer;
      typedef typename traits_base::mapped_const_pointer mapped_const_pointer;
      typedef typename traits_base::mapped_reference 	mapped_reference;
      typedef typename traits_base::mapped_const_reference mapped_const_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 				point_const_iterator;
#ifdef PB_DS_DATA_TRUE_INDICATOR
      typedef pointer 					point_iterator;
#else
      typedef point_const_iterator 			point_iterator;
#endif

      typedef point_iterator 				iterator;
      typedef point_const_iterator 			const_iterator;

      /// Conditional destructor.
      template<typename Size_Type>
        class cond_dtor
        {
	public:
	  cond_dtor(value_vector a_vec, iterator& r_last_it, 
		    Size_Type total_size) 
	  : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size),
	    m_no_action(false)
	  { }

	  ~cond_dtor()
	  {
	    if (m_no_action)
	      return;
	    iterator it = m_a_vec;
	    while (it != m_r_last_it)
	      {
		it->~value_type();
		++it;
	      }
	    
	    if (m_max_size > 0)
	      value_allocator().deallocate(m_a_vec, m_max_size);
	  }

	  inline void
	  set_no_action()
	  { m_no_action = true; }
	  
	protected:
	  value_vector 		m_a_vec;
	  iterator& 		m_r_last_it;
	  const Size_Type 	m_max_size;
	  bool 			m_no_action;
       };
      
      typedef typename traits_type::node_update 	node_update;
      typedef typename traits_type::node_iterator 	node_iterator;
      typedef typename traits_type::node_const_iterator	node_const_iterator;


      PB_DS_OV_TREE_NAME();

      PB_DS_OV_TREE_NAME(const Cmp_Fn&);

      PB_DS_OV_TREE_NAME(const Cmp_Fn&, const node_update&);

      PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC&);

      ~PB_DS_OV_TREE_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[](key_const_reference r_key)
      {
#ifdef PB_DS_DATA_TRUE_INDICATOR
	PB_DS_ASSERT_VALID((*this))
	point_iterator it = lower_bound(r_key);
	if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it)))
	  {
	    PB_DS_CHECK_KEY_EXISTS(r_key)
	    PB_DS_ASSERT_VALID((*this))
	     return it->second;
	  }
	return insert_new_val(it, std::make_pair(r_key, mapped_type()))->second;
#else
	insert(r_key);
	return traits_base::s_null_type;
#endif
      }

      inline std::pair<point_iterator, bool>
      insert(const_reference r_value)
      {
	PB_DS_ASSERT_VALID((*this))
	key_const_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)))
	  {
	    PB_DS_ASSERT_VALID((*this))
	    PB_DS_CHECK_KEY_EXISTS(r_key)
	    return std::make_pair(it, false);
	  }

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

      inline point_iterator
      lower_bound(key_const_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::operator()(PB_DS_V2F(*mid_it), r_key))
	      it = ++mid_it;
	    else
	      e_it = mid_it;
	  }
	return it;
      }

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

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

	PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
	return pot_it;
      }

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

      inline point_iterator
      find(key_const_reference r_key)
      {
	PB_DS_ASSERT_VALID((*this))
	iterator pot_it = lower_bound(r_key);
	if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it)))
	  {
	    PB_DS_CHECK_KEY_EXISTS(r_key)
	    return pot_it;
	  }

	PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
	return end();
      }

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

      bool
      erase(key_const_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(key_const_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; }

      /// Returns a const node_iterator corresponding to the node at the
      /// root of the tree.
      inline node_const_iterator
      node_begin() const;

      /// Returns a node_iterator corresponding to the node at the
      /// root of the tree.
      inline node_iterator
      node_begin();

      /// Returns a const node_iterator corresponding to a node just
      /// after a leaf of the tree.
      inline node_const_iterator
      node_end() const;

      /// Returns a node_iterator corresponding to a node just
      /// after a leaf of the tree.
      inline node_iterator
      node_end();

    private:

      inline void
      update(node_iterator, 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)
      {
#ifdef PB_DS_REGRESSION
	typename _Alloc::group_adjustor adjust(m_size);
#endif

	PB_DS_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);
	PB_DS_ASSERT_VALID((*this))
	return ret_it;
      }

#ifdef _GLIBCXX_DEBUG
      void
      assert_valid(const char*, int) const;

      void
      assert_iterators(const char*, int) const;
#endif

      template<typename It>
      It
      erase_imp(It);

      inline node_const_iterator
      PB_DS_node_begin_imp() const;

      inline node_const_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_NAME
#undef PB_DS_OV_TREE_TRAITS_BASE
#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_CONST_NODE_ITERATOR_NAME
  } // namespace detail
} // namespace __gnu_pbds
