/* Boost.MultiIndex test for standard list operations.
 *
 * Copyright 2003-2010 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_list_ops.hpp"

#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <vector>
#include "pre_multi_index.hpp"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/test/test_tools.hpp>

using namespace boost::multi_index;

#undef CHECK_EQUAL
#define CHECK_EQUAL(p,check_seq) \
{\
  int v[]={BOOST_PP_SEQ_ENUM(check_seq)};\
  std::size_t size_v=sizeof(v)/sizeof(int);\
  BOOST_CHECK(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\
  BOOST_CHECK(std::equal((p).begin(),(p).end(),&v[0]));\
}

#undef CHECK_VOID_RANGE
#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second)

struct is_even
{
  bool operator()(int x)const{return x%2==0;}
};

template <int m>
struct same_integral_div
{
  bool operator()(int x,int y)const{return (x/m)==(y/m);}
};

template <typename Container,typename Compare>
bool is_sorted(
  const Container& c,const Compare& comp=Compare())
{
  if(c.empty())return true;

  typedef typename Container::const_iterator const_iterator;
  for(const_iterator it(c.begin());;){
    const_iterator it2=it;
    ++it2;
    if(it2==c.end())return true;
    if(comp(*it2,*it))return false;
    it=it2;
  }
}

#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
/* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
 * expressions of the form sizeof(x) where x is an array local to a
 * template function.
 */

#pragma parse_func_templ off
#endif

template<typename Sequence>
static void test_list_ops_unique_seq(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
{
  typedef typename nth_index<Sequence,1>::type sequenced_index;

  Sequence         ss,ss2;
  sequenced_index &si=get<1>(ss),&si2=get<1>(ss2);

  si.push_front(0);                       /* 0        */
  si.push_front(4);                       /* 40       */
  ss.insert(2);                           /* 402      */
  ss.insert(5);                           /* 4025     */
  si.push_front(3);                       /* 34025    */
  si.push_back(6);                        /* 340256   */
  si.push_back(1);                        /* 3402561  */
  si.insert(project<1>(ss,ss.find(2)),8); /* 34082561 */
  si2=si;

  CHECK_EQUAL(si,(3)(4)(0)(8)(2)(5)(6)(1));

  si.remove(8);
  CHECK_EQUAL(si,(3)(4)(0)(2)(5)(6)(1));

  si.remove_if(is_even());

  CHECK_EQUAL(si,(3)(5)(1));

  si.splice(si.end(),si2);
  CHECK_EQUAL(si,(3)(5)(1)(4)(0)(8)(2)(6));
  CHECK_EQUAL(si2,(3)(5)(1));

  si.splice(project<1>(ss,ss.find(4)),si,project<1>(ss,ss.find(8)));
  CHECK_EQUAL(si,(3)(5)(1)(8)(4)(0)(2)(6));
  si2.clear();
  si2.splice(si2.begin(),si,si.begin());

  si.splice(si.end(),si2,si2.begin());
  CHECK_EQUAL(si,(5)(1)(8)(4)(0)(2)(6)(3));
  BOOST_CHECK(si2.empty());

  si2.splice(si2.end(),si,project<1>(ss,ss.find(0)),project<1>(ss,ss.find(6)));
  CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));
  CHECK_EQUAL(si2,(0)(2));

  si.splice(si.begin(),si,si.begin(),si.begin());
  CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));

  si.splice(project<1>(ss,ss.find(8)),si,project<1>(ss,ss.find(4)),si.end());
  CHECK_EQUAL(si,(5)(1)(4)(6)(3)(8));

  si.sort();
  si2.sort();
  BOOST_CHECK(is_sorted(si,std::less<int>()));
  BOOST_CHECK(is_sorted(si2,std::less<int>()));

  si.merge(si2);
  BOOST_CHECK(is_sorted(si,std::less<int>()));
  BOOST_CHECK(si2.empty());

  {
    Sequence         ss3(ss);
    sequenced_index &si3=get<1>(ss3);

    si3.sort(std::greater<int>());
    si.reverse();
    BOOST_CHECK(si==si3);
  }

  si2.splice(si2.end(),si,project<1>(ss,ss.find(6)),project<1>(ss,ss.find(3)));
  CHECK_EQUAL(si2,(6)(5)(4));

  si.merge(si2,std::greater<int>());
  BOOST_CHECK(is_sorted(si,std::greater<int>()));
  BOOST_CHECK(si2.empty());

  /* testcase for bug reported at
   * https://svn.boost.org/trac/boost/ticket/3076
   */
  {
    Sequence         ss3;
    sequenced_index &si3=get<1>(ss3);
    si3.sort();
  }
}

template<typename Sequence>
static void test_list_ops_non_unique_seq(
  BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
{
  typedef typename Sequence::iterator iterator;

  Sequence ss;
  for(int i=0;i<10;++i){
    ss.push_back(i);
    ss.push_back(i);
    ss.push_front(i);
    ss.push_front(i);
  } /* 9988776655443322110000112233445566778899 */

  ss.unique();
  CHECK_EQUAL(
    ss,
    (9)(8)(7)(6)(5)(4)(3)(2)(1)(0)
    (1)(2)(3)(4)(5)(6)(7)(8)(9));

  iterator it=ss.begin();
  for(int j=0;j<9;++j,++it){} /* it points to o */

  Sequence ss2;
  ss2.splice(ss2.end(),ss,ss.begin(),it);
  ss2.reverse();
  ss.merge(ss2);
  CHECK_EQUAL(
    ss,
    (0)(1)(1)(2)(2)(3)(3)(4)(4)(5)(5)
    (6)(6)(7)(7)(8)(8)(9)(9));

  ss.unique(same_integral_div<3>());
  CHECK_EQUAL(ss,(0)(3)(6)(9));

  ss.unique(same_integral_div<1>());
  CHECK_EQUAL(ss,(0)(3)(6)(9));

  /* testcases for bugs reported at
   * http://lists.boost.org/boost-users/2006/09/22604.php
   */
  {
    Sequence ss,ss2;
    ss.push_back(0);
    ss2.push_back(0);
    ss.splice(ss.end(),ss2,ss2.begin());
    CHECK_EQUAL(ss,(0)(0));
    BOOST_CHECK(ss2.empty());

    ss.clear();
    ss2.clear();
    ss.push_back(0);
    ss2.push_back(0);
    ss.splice(ss.end(),ss2,ss2.begin(),ss2.end());
    CHECK_EQUAL(ss,(0)(0));
    BOOST_CHECK(ss2.empty());

    ss.clear();
    ss2.clear();
    ss.push_back(0);
    ss2.push_back(0);
    ss.merge(ss2);
    CHECK_EQUAL(ss,(0)(0));
    BOOST_CHECK(ss2.empty());

    typedef typename Sequence::value_type value_type;
    ss.clear();
    ss2.clear();
    ss.push_back(0);
    ss2.push_back(0);
    ss.merge(ss2,std::less<value_type>());
    CHECK_EQUAL(ss,(0)(0));
    BOOST_CHECK(ss2.empty());
  }
}

#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
#pragma parse_func_templ reset
#endif

void test_list_ops()
{
  typedef multi_index_container<
    int,
    indexed_by<
      ordered_unique<identity<int> >,
      sequenced<>
    >
  > sequenced_set;
  
  /* MSVC++ 6.0 chokes on test_list_ops_unique_seq without this
   * explicit instantiation
   */
  sequenced_set ss;
  test_list_ops_unique_seq<sequenced_set>();


  typedef multi_index_container<
    int,
    indexed_by<
      ordered_unique<identity<int> >,
      random_access<>
    >
  > random_access_set;
  
  random_access_set rs;
  test_list_ops_unique_seq<random_access_set>();

  typedef multi_index_container<
    int,
    indexed_by<sequenced<> >
  > int_list;

  int_list il;
  test_list_ops_non_unique_seq<int_list>();

  typedef multi_index_container<
    int,
    indexed_by<random_access<> >
  > int_vector;

  int_vector iv;
  test_list_ops_non_unique_seq<int_vector>();
}
