/* Boost.MultiIndex test for safe_mode.
 *
 * Copyright 2003-2008 Joaquin M Lopez Munoz.
 * 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)
 *
 * See http://www.boost.org/libs/multi_index for library home page.
 */

#include "test_safe_mode.hpp"

#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include "pre_multi_index.hpp"
#include "employee.hpp"
#include "pair_of_ints.hpp"
#include <stdexcept>
#include <boost/test/test_tools.hpp>

using namespace boost::multi_index;

#define TRY_SAFE_MODE \
try{

#define CATCH_SAFE_MODE(err) \
  throw std::runtime_error("safe mode violation not detected");\
}catch(const safe_mode_exception& e){\
  if(e.error_code!=(err))throw std::runtime_error(\
    "safe mode violation not expected");\
}

template<typename Policy>
static void local_test_safe_mode(
  std::forward_iterator_tag
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
{
  typedef typename Policy::container      container;
  typedef typename Policy::index_type     index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  container   c,c2;
  index_type& i=Policy::index_from_container(c);
  index_type& i2=Policy::index_from_container(c2);
  Policy::insert(i,Policy::some_value());

  TRY_SAFE_MODE
    iterator it;
    iterator it2=i.begin();
    it2=it;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it;
    value_type e=*it;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)
  
  TRY_SAFE_MODE
    iterator it=i.end();
    value_type e=*it;
  CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)

  TRY_SAFE_MODE
    iterator it=i.end();
    ++it;
  CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator)

  TRY_SAFE_MODE
    iterator it;
    iterator it2;
    bool b=(it==it2);
    b=true; /* avoid warning about unused var */
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it=i.begin();
    iterator it2;
    bool b=(it==it2);
    b=true; /* avoid warning about unused var */
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it=i.begin();
    iterator it2=i2.begin();
    bool b=(it==it2);
    b=true; /* avoid warning about unused var */
  CATCH_SAFE_MODE(safe_mode::not_same_owner)

  TRY_SAFE_MODE
    i.erase(i.end(),i.begin());
  CATCH_SAFE_MODE(safe_mode::invalid_range)

  TRY_SAFE_MODE
    iterator it;
    Policy::insert(i,it,Policy::some_value());
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    i.erase(i.end());
  CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)

  TRY_SAFE_MODE
    iterator it=i.begin();
    Policy::insert(i2,it,Policy::some_value());
  CATCH_SAFE_MODE(safe_mode::not_owner)

  TRY_SAFE_MODE
    iterator it=i.begin();
    iterator it2=i2.end();
    i2.erase(it,it2);
  CATCH_SAFE_MODE(safe_mode::not_owner)

  TRY_SAFE_MODE
    iterator it=Policy::insert(i,Policy::another_value());
    i.erase(it);
    i.erase(it);
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    container   c3(c);
    index_type& i3=Policy::index_from_container(c3);
    iterator it=Policy::insert(i3,Policy::another_value());
    i3.clear();
    i3.erase(it);
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it;
    {
      container   c3;
      index_type& i3=Policy::index_from_container(c3);
      it=i3.end();
    }
    it=it;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it;
    {
      container   c3;
      index_type& i3=Policy::index_from_container(c3);
      it=Policy::insert(i3,Policy::some_value());
    }
    value_type e=*it;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    iterator it;
    {
      container   c3;
      index_type& i3=Policy::index_from_container(c3);
      it=Policy::insert(i3,Policy::some_value());
    }
    iterator it2;
    it2=it;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    container   c3(c);
    container   c4;
    index_type& i3=Policy::index_from_container(c3);
    index_type& i4=Policy::index_from_container(c4);
    iterator  it=i3.begin();
    i3.swap(i4);
    i3.erase(it);
  CATCH_SAFE_MODE(safe_mode::not_owner)

  /* this, unlike the previous case, is indeed correct, test safe mode
   * gets it right
   */
  { 
    container   c3(c);
    container   c4;
    index_type& i3=Policy::index_from_container(c3);
    index_type& i4=Policy::index_from_container(c4);
    iterator  it=i3.begin();
    i3.swap(i4);
    i4.erase(it);
  }

  TRY_SAFE_MODE
    iterator it=i.end();
    typename container::iterator it2=project<0>(c2,it);
  CATCH_SAFE_MODE(safe_mode::not_owner)

  TRY_SAFE_MODE
    iterator it=Policy::insert(i,Policy::another_value());
    typename container::iterator it2=project<0>(c,it);
    i.erase(it);
    value_type e=*it2;
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  /* testcase for bug reported at
   * http://lists.boost.org/boost-users/2006/02/17230.php
   */
  {
    container c3(c);
    index_type& i3=Policy::index_from_container(c3);
    iterator it=i3.end();
    i3.clear();
    it=i3.end();
  }

  /* testcase for doppelganger bug of that discovered for STLport at
   * http://lists.boost.org/Archives/boost/2006/04/102740.php
   */
  {
    container c3;
    index_type& i3=Policy::index_from_container(c3);
    iterator it=i3.end();
    i3.clear();
    it=it;
    BOOST_CHECK(it==i3.end());
  }
}

template<typename Policy>
static void local_test_safe_mode(
  std::bidirectional_iterator_tag
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
{
  ::local_test_safe_mode<Policy>(std::forward_iterator_tag());

  typedef typename Policy::container      container;
  typedef typename Policy::index_type     index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  container   c;
  index_type& i=Policy::index_from_container(c);
  Policy::insert(i,Policy::some_value());

  TRY_SAFE_MODE
    iterator it=i.begin();
    --it;
  CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator)
}

template<typename Policy>
static void local_test_safe_mode(
  std::random_access_iterator_tag
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
{
  ::local_test_safe_mode<Policy>(std::bidirectional_iterator_tag());

  typedef typename Policy::container      container;
  typedef typename Policy::index_type     index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  container   c;
  index_type& i=Policy::index_from_container(c);
  Policy::insert(i,Policy::some_value());

  TRY_SAFE_MODE
    iterator it=i.begin();
    it+=2;
  CATCH_SAFE_MODE(safe_mode::out_of_bounds)

  TRY_SAFE_MODE
    iterator it=i.begin();
    it-=1;
  CATCH_SAFE_MODE(safe_mode::out_of_bounds)
}

template<typename Policy>
static void local_test_safe_mode(BOOST_EXPLICIT_TEMPLATE_TYPE(Policy))
{
  typedef typename Policy::index_type::iterator::iterator_category category;
  ::local_test_safe_mode<Policy>(category());
}

template<typename Policy>
static void local_test_safe_mode_with_rearrange(
  BOOST_EXPLICIT_TEMPLATE_TYPE(Policy))
{
  ::local_test_safe_mode<Policy>();

  typedef typename Policy::container      container;
  typedef typename Policy::index_type     index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  container   c;
  index_type& i=Policy::index_from_container(c);
  Policy::insert(i,Policy::some_value());

  TRY_SAFE_MODE
    iterator it;
    i.splice(it,i,i.begin(),i.end());
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    container   c2(c);
    index_type& i2=Policy::index_from_container(c2);
    iterator    it2=i2.begin();
    iterator    it=i.begin();
    i.splice(it2,i2,it);
  CATCH_SAFE_MODE(safe_mode::not_owner)

  TRY_SAFE_MODE
    i.splice(i.begin(),i,i.begin(),i.end());
  CATCH_SAFE_MODE(safe_mode::inside_range)

  TRY_SAFE_MODE
    i.splice(i.begin(),i,i.end(),i.begin());
  CATCH_SAFE_MODE(safe_mode::invalid_range)

  TRY_SAFE_MODE
    i.splice(i.begin(),i);
  CATCH_SAFE_MODE(safe_mode::same_container)

  TRY_SAFE_MODE
    iterator it;
    i.relocate(it,i.begin(),i.end());
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    i.relocate(i.begin(),i.begin(),i.end());
  CATCH_SAFE_MODE(safe_mode::inside_range)

  TRY_SAFE_MODE
    i.relocate(i.begin(),i.end(),i.begin());
  CATCH_SAFE_MODE(safe_mode::invalid_range)
}

template<typename MultiIndexContainer,int N>
struct index_policy_base
{
  typedef MultiIndexContainer                    container;
  typedef typename 
    boost::multi_index::detail::prevent_eti<
      container,
    typename nth_index<container,N>::type>::type index_type;

  static index_type& index_from_container(container& c){return get<N>(c);}
};

template<typename MultiIndexContainer,int N>
struct key_based_index_policy_base:
  index_policy_base<MultiIndexContainer,N>
{
  typedef index_policy_base<MultiIndexContainer,N> super;

  typedef typename super::container       container;
  typedef typename super::index_type      index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  static iterator insert(index_type& i,const value_type& v)
  {
    return i.insert(v).first;
  }

  static iterator insert(index_type& i,iterator it,const value_type& v)
  {
    return i.insert(it,v);
  }
};

template<typename MultiIndexContainer,int N>
struct non_key_based_index_policy_base:
  index_policy_base<MultiIndexContainer,N>
{
  typedef index_policy_base<MultiIndexContainer,N> super;

  typedef typename super::container       container;
  typedef typename super::index_type      index_type;
  typedef typename index_type::value_type value_type;
  typedef typename index_type::iterator   iterator;

  static iterator insert(index_type& i,const value_type& v)
  {
    return i.push_back(v).first;
  }

  static iterator insert(index_type& i,iterator it,const value_type& v)
  {
    return i.insert(it,v).first;
  }
};

struct employee_set_policy_base
{
  static employee    some_value(){return employee(0,"Joe",31,1123);}
  static employee    another_value(){return employee(1,"Robert",27,5601);}
};

struct employee_set_policy:
  employee_set_policy_base,
  key_based_index_policy_base<employee_set,0>
{};

struct employee_set_by_name_policy:
  employee_set_policy_base,
  key_based_index_policy_base<employee_set,1>
{};

struct employee_set_as_inserted_policy:
  employee_set_policy_base,
  non_key_based_index_policy_base<employee_set,3>
{};

struct employee_set_randomly_policy:
  employee_set_policy_base,
  non_key_based_index_policy_base<employee_set,5>
{};

template<typename IntegralBimap>
static void test_integral_bimap(BOOST_EXPLICIT_TEMPLATE_TYPE(IntegralBimap))
{
  typedef typename IntegralBimap::value_type value_type;
  typedef typename IntegralBimap::iterator   iterator;

  TRY_SAFE_MODE
    IntegralBimap bm;
    iterator it=bm.insert(value_type(0,0)).first;
    bm.insert(value_type(1,1));
    bm.modify(it,increment_first);
    value_type v=*it;
    v.first=0; /* avoid warning about unused var */
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)

  TRY_SAFE_MODE
    IntegralBimap bm;
    iterator it=bm.insert(value_type(0,0)).first;
    bm.insert(value_type(1,1));
    bm.modify(it,increment_second);
    pair_of_ints v=*it;
    v.first=0; /* avoid warning about unused var */
  CATCH_SAFE_MODE(safe_mode::invalid_iterator)
}

void test_safe_mode()
{
  local_test_safe_mode<employee_set_policy>();
  local_test_safe_mode<employee_set_by_name_policy>();
  local_test_safe_mode_with_rearrange<employee_set_as_inserted_policy>();
  local_test_safe_mode_with_rearrange<employee_set_randomly_policy>();

  typedef multi_index_container<
    pair_of_ints,
    indexed_by<
      ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
      ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
  > bimap0_type;

  /* MSVC++ 6.0 chokes on test_integral_bimap without this
   * explicit instantiation
   */
  bimap0_type bm0;
  test_integral_bimap<bimap0_type>();

  typedef multi_index_container<
    pair_of_ints,
    indexed_by<
      ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
      hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
  > bimap1_type;

  bimap1_type bm1;
  test_integral_bimap<bimap1_type>();

  typedef multi_index_container<
    pair_of_ints,
    indexed_by<
      hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
      ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
  > bimap2_type;

  bimap2_type bm2;
  test_integral_bimap<bimap2_type>();

  typedef multi_index_container<
    pair_of_ints,
    indexed_by<
      hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
      hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
  > bimap3_type;

  bimap3_type bm3;
  test_integral_bimap<bimap3_type>();
}
