//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Peter Dimov 2002-2005, 2007.
// (C) Copyright Ion Gaztanaga 2006-2009.
// 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/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/enable_shared_from_this.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
#include "get_process_id_name.hpp"


#include <boost/interprocess/sync/upgradable_lock.hpp>
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>

using namespace boost::interprocess;

class base_class
{
   public:
   virtual ~base_class()
   {}
};

class derived_class
   :  public base_class
{
   public:
   virtual ~derived_class()
   {}
};

int simple_test()
{
   typedef allocator<base_class, managed_shared_memory::segment_manager>
      base_class_allocator;
   typedef deleter<base_class, managed_shared_memory::segment_manager>
      base_deleter_t;
   typedef shared_ptr<base_class, base_class_allocator, base_deleter_t>    base_shared_ptr;
   typedef weak_ptr<base_class, base_class_allocator, base_deleter_t>      base_weak_ptr;

   std::string process_name;
   test::get_process_id_name(process_name);

   shared_memory_object::remove(process_name.c_str());
   {
      managed_shared_memory shmem(create_only, process_name.c_str(), 10000);

      {
         base_shared_ptr s_ptr(base_shared_ptr::pointer(0), 
                           base_class_allocator(shmem.get_segment_manager()), 
                           base_deleter_t(shmem.get_segment_manager()));

         base_shared_ptr s_ptr2(shmem.construct<base_class>("base_class")(), 
                              base_class_allocator(shmem.get_segment_manager()), 
                              base_deleter_t(shmem.get_segment_manager()));

         base_shared_ptr s_ptr3(offset_ptr<derived_class>(shmem.construct<derived_class>("derived_class")()), 
                              base_class_allocator(shmem.get_segment_manager()), 
                              base_deleter_t(shmem.get_segment_manager()));

         if(s_ptr3.get_deleter()   == 0){
            return 1;
         }
         //if(s_ptr3.get_allocator() == 0){
            //return 1;
         //}

         base_shared_ptr s_ptr_empty;

         if(s_ptr_empty.get_deleter()   != 0){
            return 1;
         }
         //if(s_ptr_empty.get_allocator() != 0){
            //return 1;
         //}
      }
   }
   shared_memory_object::remove(process_name.c_str());
   return 0;
}

int string_shared_ptr_vector_insertion_test()
{
   //Allocator of chars
   typedef allocator<char, managed_shared_memory::segment_manager >
      char_allocator_t;

   //A shared memory string class
   typedef basic_string<char, std::char_traits<char>,
                        char_allocator_t> string_t;

   //A shared memory string allocator
   typedef allocator<string_t, managed_shared_memory::segment_manager>
      string_allocator_t;

   //A deleter for shared_ptr<> that erases a shared memory string
   typedef deleter<string_t, managed_shared_memory::segment_manager> 
      string_deleter_t;

   //A shared pointer that points to a shared memory string and its instantiation
   typedef shared_ptr<string_t, string_allocator_t, string_deleter_t> string_shared_ptr_t;

   //An allocator for shared pointers to a string in shared memory 
   typedef allocator<string_shared_ptr_t, managed_shared_memory::segment_manager>
      string_shared_ptr_allocator_t;

   //A weak pointer that points to a shared memory string and its instantiation
   typedef weak_ptr<string_t, string_allocator_t, string_deleter_t> string_weak_ptr_t;

   //An allocator for weak pointers to a string in shared memory 
   typedef allocator<string_weak_ptr_t, managed_shared_memory::segment_manager >
      string_weak_ptr_allocator_t;

   //A vector of shared pointers to strings (all in shared memory) and its instantiation
   typedef vector<string_shared_ptr_t, string_shared_ptr_allocator_t>
      string_shared_ptr_vector_t;

   //A vector of weak pointers to strings (all in shared memory) and its instantiation
   typedef vector<string_weak_ptr_t, string_weak_ptr_allocator_t>
      string_weak_ptr_vector_t;

   std::string process_name;
   test::get_process_id_name(process_name);

   //A shared memory managed memory classes
   shared_memory_object::remove(process_name.c_str());
   {
      managed_shared_memory shmem(create_only, process_name.c_str(), 20000);

      {  
         const int NumElements = 100;
         //Construct the allocator of strings
         string_allocator_t string_allocator(shmem.get_segment_manager());
         //Construct the allocator of a shared_ptr to string
         string_shared_ptr_allocator_t string_shared_ptr_allocator(shmem.get_segment_manager());
         //Construct the allocator of a shared_ptr to string
         string_weak_ptr_allocator_t string_weak_ptr_allocator(shmem.get_segment_manager());
         //This is a string deleter using destroy_ptr() function of the managed_shared_memory
         string_deleter_t deleter(shmem.get_segment_manager());
         //Create a string in shared memory, to avoid leaks with exceptions use
         //scoped ptr until we store this pointer in the shared ptr
         scoped_ptr<string_t, string_deleter_t> scoped_string
         (shmem.construct<string_t>(anonymous_instance)(string_allocator),
            deleter);
         //Now construct a shared pointer to a string
         string_shared_ptr_t string_shared_ptr (scoped_string.get(),
                                                string_shared_ptr_allocator,
                                                deleter);
         //Check use count is just one
         if(!string_shared_ptr.unique()){
            return 1;
         }
         //We don't need the scoped_ptr anonymous since the raw pointer is in the shared ptr
         scoped_string.release();
         //Now fill a shared memory vector of shared_ptrs to a string
         string_shared_ptr_vector_t my_sharedptr_vector(string_shared_ptr_allocator);
         my_sharedptr_vector.insert(my_sharedptr_vector.begin(), NumElements, string_shared_ptr);
         //Insert in the middle to test movability
         my_sharedptr_vector.insert(my_sharedptr_vector.begin() + my_sharedptr_vector.size()/2, NumElements, string_shared_ptr);
         //Now check the shared count is the objects contained in the
         //vector plus string_shared_ptr
         if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
            return 1;
         }
         //Now create a weak ptr from the shared_ptr
         string_weak_ptr_t string_weak_ptr (string_shared_ptr);
         //Use count should remain the same
         if(string_weak_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
            return 1;
         }
         //Now reset the local shared_ptr and check use count
         string_shared_ptr.reset();
         if(string_weak_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size())){
            return 1;
         }
         //Now reset the local shared_ptr's use count should be zero
         if(string_shared_ptr.use_count() != 0){
            return 1;
         }
         //Now recreate the shared ptr from the weak ptr
         //and recheck use count
         string_shared_ptr = string_shared_ptr_t(string_weak_ptr);
         if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
            return 1;
         }
         //Now fill a vector of weak_ptr-s
         string_weak_ptr_vector_t my_weakptr_vector(string_weak_ptr_allocator);
         my_weakptr_vector.insert(my_weakptr_vector.begin(), NumElements, string_weak_ptr);      
         //The shared count should remain the same
         if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
            return 1;
         }
         //So weak pointers should be fine
         string_weak_ptr_vector_t::iterator beg = my_weakptr_vector.begin(),
                                          end = my_weakptr_vector.end();
         for(;beg != end; ++beg){
            if(beg->expired()){
               return 1;
            }
            //The shared pointer constructed from weak ptr should
            //be the same as the original, since all weak pointer
            //point the the same object
            if(string_shared_ptr_t(*beg) != string_shared_ptr){
               return 1;
            }
         }
         //Now destroy all the shared ptr-s of the shared ptr vector
         my_sharedptr_vector.clear();
         //The only alive shared ptr should be the local one
         if(string_shared_ptr.use_count() != 1){
            return 1;
         }
         //Now we invalidate the last alive shared_ptr
         string_shared_ptr.reset();
         //Now all weak pointers should have expired
         beg = my_weakptr_vector.begin();
         end = my_weakptr_vector.end();
         for(;beg != end; ++beg){
            if(!beg->expired()){
               return 1;
            }
            bool success = false;
            //Now this should throw
            try{
               string_shared_ptr_t dummy(*beg);
               //We should never reach here
               return 1;
            }
            catch(const boost::interprocess::bad_weak_ptr &){
               success = true;
            }
            if(!success){
               return 1;
            }
         }
         //Clear weak ptr vector
         my_weakptr_vector.clear();
         //Now lock returned shared ptr should return null
         if(string_weak_ptr.lock().get()){
            return 1;
         }
         //Reset weak_ptr
         string_weak_ptr.reset();
      }
   }
   shared_memory_object::remove(process_name.c_str());
   return 0;
}
//
//  This part is taken from shared_ptr_basic_test.cpp
//
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//  Copyright (c) 2006 Ion Gaztanaga
//
// 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)
//

static int cnt = 0;

struct X
{
   X(){ ++cnt;   }
   // virtual destructor deliberately omitted
   ~X(){   --cnt;    }

   virtual int id() const
   {  return 1;   }

   private:
   X(X const &);
   X & operator= (X const &);
};

struct Y: public X
{
   Y(){  ++cnt;   }
   ~Y(){ --cnt;   }

   virtual int id() const
   {  return 2;   }

   private:
   Y(Y const &);
   Y & operator= (Y const &);
};

int * get_object()
{  ++cnt;   return &cnt;   }

void release_object(int * p)
{  BOOST_TEST(p == &cnt);  --cnt;   }

template<class T, class A, class D> 
void test_is_X(shared_ptr<T, A, D> const & p)
{
   BOOST_TEST(p->id() == 1);
   BOOST_TEST((*p).id() == 1);
}

template<class T, class A, class D> 
void test_is_X(weak_ptr<T, A, D> const & p)
{
   BOOST_TEST(p.get() != 0);
   BOOST_TEST(p.get()->id() == 1);
}

template<class T, class A, class D> 
void test_is_Y(shared_ptr<T, A, D> const & p)
{
   BOOST_TEST(p->id() == 2);
   BOOST_TEST((*p).id() == 2);
}

template<class T, class A, class D> 
void test_is_Y(weak_ptr<T, A, D> const & p)
{
   shared_ptr<T, A, D> q = p.lock();
   BOOST_TEST(q.get() != 0);
   BOOST_TEST(q->id() == 2);
}

template<class T, class T2> 
void test_eq(T const & a, T2 const & b)
{
   BOOST_TEST(a == b);
   BOOST_TEST(!(a != b));
   BOOST_TEST(!(a < b));
   BOOST_TEST(!(b < a));
}

template<class T, class T2> 
void test_ne(T const & a, T2 const & b)
{
   BOOST_TEST(!(a == b));
   BOOST_TEST(a != b);
   BOOST_TEST(a < b || b < a);
   BOOST_TEST(!(a < b && b < a));
}

template<class T, class U, class A, class D, class D2>
void test_shared(weak_ptr<T, A, D> const & a, weak_ptr<U, A, D2> const & b)
{
   BOOST_TEST(!(a < b));
   BOOST_TEST(!(b < a));
}

template<class T, class U, class A, class D, class D2>
void test_nonshared(weak_ptr<T, A, D> const & a, weak_ptr<U, A, D2> const & b)
{
   BOOST_TEST(a < b || b < a);
   BOOST_TEST(!(a < b && b < a));
}

template<class T, class U>
void test_eq2(T const & a, U const & b)
{
   BOOST_TEST(a == b);
   BOOST_TEST(!(a != b));
}

template<class T, class U>
void test_ne2(T const & a, U const & b)
{
   BOOST_TEST(!(a == b));
   BOOST_TEST(a != b);
}

template<class T, class A, class D>
void test_is_zero(shared_ptr<T, A, D> const & p)
{
   BOOST_TEST(!p);
   BOOST_TEST(p.get() == 0);
}

template<class T, class A, class D>
void test_is_nonzero(shared_ptr<T, A, D> const & p)
{
   // p? true: false is used to test p in a boolean context.
   // BOOST_TEST(p) is not guaranteed to test the conversion,
   // as the macro might test !!p instead.
   BOOST_TEST(p? true: false);
   BOOST_TEST(p.get() != 0);
}

int basic_shared_ptr_test()
{
   typedef allocator<void, managed_shared_memory::segment_manager>
      v_allocator_t;

   typedef deleter<X, managed_shared_memory::segment_manager>
      x_deleter_t;

   typedef deleter<Y, managed_shared_memory::segment_manager>
      y_deleter_t;

   typedef shared_ptr<X, v_allocator_t, x_deleter_t> x_shared_ptr;

   typedef shared_ptr<Y, v_allocator_t, y_deleter_t> y_shared_ptr;

   typedef weak_ptr<X, v_allocator_t, x_deleter_t> x_weak_ptr;

   typedef weak_ptr<Y, v_allocator_t, y_deleter_t> y_weak_ptr;

   std::string process_name;
   test::get_process_id_name(process_name);

   shared_memory_object::remove(process_name.c_str());
   {
      managed_shared_memory shmem(create_only, process_name.c_str(), 10000);
      {
         v_allocator_t  v_allocator (shmem.get_segment_manager());
         x_deleter_t    x_deleter   (shmem.get_segment_manager());
         y_deleter_t    y_deleter   (shmem.get_segment_manager());

         y_shared_ptr p (shmem.construct<Y>(anonymous_instance)(), v_allocator, y_deleter);
         x_shared_ptr p2(shmem.construct<X>(anonymous_instance)(), v_allocator, x_deleter);

         test_is_nonzero(p);
         test_is_nonzero(p2);
         test_is_Y(p);
         test_is_X(p2);
         test_ne(p, p2);

         {
            shared_ptr<X, v_allocator_t, y_deleter_t> q(p);
            test_eq(p, q);
         }

         y_shared_ptr p3 (dynamic_pointer_cast<Y>(p));
         shared_ptr<Y, v_allocator_t, x_deleter_t> p4 (dynamic_pointer_cast<Y>(p2));
         test_is_nonzero(p3);
         test_is_zero(p4);
         BOOST_TEST(p.use_count() == 2);
         BOOST_TEST(p2.use_count() == 1);
         BOOST_TEST(p3.use_count() == 2);
         test_is_Y(p3);
         test_eq2(p, p3);
         test_ne2(p2, p4);

         shared_ptr<void, v_allocator_t, y_deleter_t> p5(p);

         test_is_nonzero(p5);
         test_eq2(p, p5);
         BOOST_TEST(p5.use_count() == 3);

         x_weak_ptr wp1(p2);

         BOOST_TEST(!wp1.expired());
         BOOST_TEST(wp1.use_count() != 0);

         p.reset();
         p2.reset();
         p3.reset();
         p4.reset();

         test_is_zero(p);
         test_is_zero(p2);
         test_is_zero(p3);
         test_is_zero(p4);

         BOOST_TEST(p5.use_count() == 1);
         BOOST_TEST(wp1.expired());
         BOOST_TEST(wp1.use_count() == 0);

         try{
            x_shared_ptr sp1(wp1);
            BOOST_ERROR("shared_ptr<X, A, D> sp1(wp1) failed to throw");
         }
         catch(boost::interprocess::bad_weak_ptr const &)
         {}

         test_is_zero(wp1.lock());

         weak_ptr<X, v_allocator_t, y_deleter_t> wp2 = static_pointer_cast<X>(p5);

         BOOST_TEST(wp2.use_count() == 1);
         test_is_Y(wp2);
         test_nonshared(wp1, wp2);

         // Scoped to not affect the subsequent use_count() tests.
         {
            shared_ptr<X, v_allocator_t, y_deleter_t> sp2(wp2);
            test_is_nonzero(wp2.lock());
         }

         y_weak_ptr wp3 = dynamic_pointer_cast<Y>(wp2.lock());

         BOOST_TEST(wp3.use_count() == 1);
         test_shared(wp2, wp3);

         weak_ptr<X, v_allocator_t, y_deleter_t> wp4(wp3);

         BOOST_TEST(wp4.use_count() == 1);
         test_shared(wp2, wp4);

         wp1 = p2;
         test_is_zero(wp1.lock());

         wp1 = p4;

         x_weak_ptr wp5;

         bool b1 = wp1 < wp5;
         bool b2 = wp5 < wp1;

         y_shared_ptr p6 = static_pointer_cast<Y>(p5);
         p5.reset();
         p6.reset();

         BOOST_TEST(wp1.use_count() == 0);
         BOOST_TEST(wp2.use_count() == 0);
         BOOST_TEST(wp3.use_count() == 0);

         // Test operator< stability for std::set< weak_ptr<> >
         // Thanks to Joe Gottman for pointing this out
         BOOST_TEST(b1 == (wp1 < wp5));
         BOOST_TEST(b2 == (wp5 < wp1));
      }

      BOOST_TEST(cnt == 0);
   }
   shared_memory_object::remove(process_name.c_str());
   return boost::report_errors();
}

struct alias_tester
{
    int v_;

    explicit alias_tester( int v ): v_( v )
    {
    }

    ~alias_tester()
    {
        v_ = 0;
    }
};

void test_alias()
{
   typedef allocator<void, managed_shared_memory::segment_manager>
      v_allocator_t;

   typedef deleter<alias_tester, managed_shared_memory::segment_manager>
      alias_tester_deleter_t;

   typedef deleter<int, managed_shared_memory::segment_manager>
      int_deleter_t;

   typedef shared_ptr<alias_tester, v_allocator_t, alias_tester_deleter_t> alias_tester_shared_ptr;

   typedef shared_ptr<int, v_allocator_t, int_deleter_t> int_shared_ptr;
   typedef shared_ptr<const int, v_allocator_t, int_deleter_t> const_int_shared_ptr;
   typedef shared_ptr<volatile int, v_allocator_t, int_deleter_t> volatile_int_shared_ptr;

   std::string process_name;
   test::get_process_id_name(process_name);

   shared_memory_object::remove(process_name.c_str());
   {
      managed_shared_memory shmem(create_only, process_name.c_str(), 10000);

      {
         int m = 0;
         int_shared_ptr p;
         int_shared_ptr p2( p, &m );

         BOOST_TEST( detail::get_pointer(p2.get()) == &m );
         BOOST_TEST( p2? true: false );
         BOOST_TEST( !!p2 );
         BOOST_TEST( p2.use_count() == p.use_count() );
         BOOST_TEST( !( p < p2 ) && !( p2 < p ) );

         p2.reset( p, static_cast<int*>(0) );

         BOOST_TEST( p2.get() == 0 );

         BOOST_TEST( p2? false: true );
         BOOST_TEST( !p2 );
         BOOST_TEST( p2.use_count() == p.use_count() );
         BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
      }

      {
         int m = 0;
         int_shared_ptr p(make_managed_shared_ptr
            (shmem.construct<int>(anonymous_instance)(), shmem));
         const_int_shared_ptr p2( p, &m );

         BOOST_TEST( detail::get_pointer(p2.get()) == &m );
         BOOST_TEST( p2? true: false );
         BOOST_TEST( !!p2 );
         BOOST_TEST( p2.use_count() == p.use_count() );
         BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
      }
   }
   shared_memory_object::remove(process_name.c_str());
}

int main()
{
   if(0 != simple_test())
      return 1;

   if(0 != string_shared_ptr_vector_insertion_test())
      return 1;

   if(0 != basic_shared_ptr_test())
      return 1;

   test_alias();
}

#include <boost/interprocess/detail/config_end.hpp>

