//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-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.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
#define BOOST_INTERPROCESS_NAMED_PROXY_HPP

#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#  pragma once
#endif

#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>

#include <new>
#include <iterator>
#include <boost/interprocess/detail/in_place_interface.hpp>
#include <boost/interprocess/detail/mpl.hpp>

#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
#include <boost/interprocess/detail/preprocessor.hpp> 
#else
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/variadic_templates_tools.hpp>
#endif   //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING

//!\file
//!Describes a proxy class that implements named allocation syntax.

namespace boost {
namespace interprocess { 
namespace detail {

#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING

template<class T, bool is_iterator, class ...Args>
struct CtorNArg : public placement_destroy<T>
{
   typedef detail::bool_<is_iterator> IsIterator;
   typedef CtorNArg<T, is_iterator, Args...> self_t;
   typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;

   self_t& operator++()
   {
      this->do_increment(IsIterator(), index_tuple_t());
      return *this;
   }

   self_t  operator++(int) {  return ++*this;   *this;  }

   CtorNArg(Args && ...args)
      :  args_(args...)
   {}

   virtual void construct_n(void *mem
                     , std::size_t num
                     , std::size_t &constructed)
   {
      T* memory      = static_cast<T*>(mem);
      for(constructed = 0; constructed < num; ++constructed){
         this->construct(memory++, IsIterator(), index_tuple_t());
         this->do_increment(IsIterator(), index_tuple_t());
      }
   }

   private:
   template<int ...IdxPack>
   void construct(void *mem, detail::true_, const index_tuple<IdxPack...>&)
   {  new((void*)mem)T(*boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }

   template<int ...IdxPack>
   void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
   {  new((void*)mem)T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }

   template<int ...IdxPack>
   void do_increment(detail::true_, const index_tuple<IdxPack...>&)
   {
      this->expansion_helper(++get<IdxPack>(args_)...);
   }
 
   template<class ...ExpansionArgs>
   void expansion_helper(ExpansionArgs &&...)
   {}

   template<int ...IdxPack>
   void do_increment(detail::false_, const index_tuple<IdxPack...>&)
   {}

   tuple<Args&...> args_;
};                                                                      

//!Describes a proxy class that implements named
//!allocation syntax.
template 
   < class SegmentManager  //segment manager to construct the object
   , class T               //type of object to build
   , bool is_iterator      //passing parameters are normal object or iterators?
   >
class named_proxy
{
   typedef typename SegmentManager::char_type char_type;
   const char_type *    mp_name;
   SegmentManager *     mp_mngr;
   mutable std::size_t  m_num;
   const bool           m_find;
   const bool           m_dothrow;

   public:
   named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
      :  mp_name(name), mp_mngr(mngr), m_num(1)
      ,  m_find(find),  m_dothrow(dothrow)
   {}

   template<class ...Args>
   T *operator()(Args &&...args) const
   {  
      CtorNArg<T, is_iterator, Args...> &&ctor_obj = CtorNArg<T, is_iterator, Args...>
         (boost::interprocess::forward<Args>(args)...);
      return mp_mngr->template 
         generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
   }

   //This operator allows --> named_new("Name")[3]; <-- syntax
   const named_proxy &operator[](std::size_t num) const
   {  m_num *= num; return *this;  }
};

#else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING

//!Function object that makes placement new
//!without arguments
template<class T>
struct Ctor0Arg   :  public placement_destroy<T>
{
   typedef Ctor0Arg self_t;

   Ctor0Arg(){}

   self_t& operator++()       {  return *this;  }
   self_t  operator++(int)    {  return *this;  }

   void construct(void *mem)
   {  new((void*)mem)T;  }

   virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
   {
      T* memory = static_cast<T*>(mem);
      for(constructed = 0; constructed < num; ++constructed)
         new((void*)memory++)T;
   }
};

////////////////////////////////////////////////////////////////
//    What the macro should generate (n == 2):
//
//    template<class T, bool is_iterator, class P1, class P2>
//    struct Ctor2Arg
//      :  public placement_destroy<T>
//    {
//       typedef detail::bool_<is_iterator> IsIterator;
//       typedef Ctor2Arg self_t;
//
//       void do_increment(detail::false_)
//       { ++m_p1; ++m_p2;  }
//
//       void do_increment(detail::true_){}
//
//       self_t& operator++()
//       {
//          this->do_increment(IsIterator());
//          return *this;
//       }
//
//       self_t  operator++(int) {  return ++*this;   *this;  }
//
//       Ctor2Arg(const P1 &p1, const P2 &p2)
//          : p1((P1 &)p_1), p2((P2 &)p_2) {}
//
//       void construct(void *mem)
//       {  new((void*)object)T(m_p1, m_p2); }
//
//       virtual void construct_n(void *mem
//                                , std::size_t num
//                                , std::size_t &constructed)
//       {
//          T* memory      = static_cast<T*>(mem);
//          for(constructed = 0; constructed < num; ++constructed){
//             this->construct(memory++, IsIterator());
//             this->do_increment(IsIterator());
//          }
//       }
//
//       private:
//       void construct(void *mem, detail::true_)
//       {  new((void*)mem)T(*m_p1, *m_p2); }
//                                                                           
//       void construct(void *mem, detail::false_)
//       {  new((void*)mem)T(m_p1, m_p2); }
//
//       P1 &m_p1; P2 &m_p2;
//    };
////////////////////////////////////////////////////////////////

//Note:
//We define template parameters as const references to
//be able to bind temporaries. After that we will un-const them.
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind lvalues with non-const references, we have to be ugly
#define BOOST_PP_LOCAL_MACRO(n)                                            \
   template<class T, bool is_iterator, BOOST_PP_ENUM_PARAMS(n, class P) >  \
   struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg)                         \
      :  public placement_destroy<T>                                       \
   {                                                                       \
      typedef detail::bool_<is_iterator> IsIterator;                       \
      typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t;             \
                                                                           \
      void do_increment(detail::true_)                                     \
         { BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); }        \
                                                                           \
      void do_increment(detail::false_){}                                  \
                                                                           \
      self_t& operator++()                                                 \
      {                                                                    \
         this->do_increment(IsIterator());                                 \
         return *this;                                                     \
      }                                                                    \
                                                                           \
      self_t  operator++(int) {  return ++*this;   *this;  }               \
                                                                           \
      BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg)                             \
         ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _) )        \
         : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {}       \
                                                                           \
      virtual void construct_n(void *mem                                   \
                        , std::size_t num                                  \
                        , std::size_t &constructed)                        \
      {                                                                    \
         T* memory      = static_cast<T*>(mem);                            \
         for(constructed = 0; constructed < num; ++constructed){           \
            this->construct(memory++, IsIterator());                       \
            this->do_increment(IsIterator());                              \
         }                                                                 \
      }                                                                    \
                                                                           \
      private:                                                             \
      void construct(void *mem, detail::true_)                             \
      {                                                                    \
         new((void*)mem) T                                                 \
         (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD, _));   \
      }                                                                    \
                                                                           \
      void construct(void *mem, detail::false_)                            \
      {                                                                    \
         new((void*)mem) T                                                 \
            (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _));   \
      }                                                                    \
                                                                           \
      BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _)           \
   };                                                                      \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()

//!Describes a proxy class that implements named
//!allocation syntax.
template 
   < class SegmentManager  //segment manager to construct the object
   , class T               //type of object to build
   , bool is_iterator      //passing parameters are normal object or iterators?
   >
class named_proxy
{
   typedef typename SegmentManager::char_type char_type;
   const char_type *    mp_name;
   SegmentManager *     mp_mngr;
   mutable std::size_t  m_num;
   const bool           m_find;
   const bool           m_dothrow;

   public:
   named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
      :  mp_name(name), mp_mngr(mngr), m_num(1)
      ,  m_find(find),  m_dothrow(dothrow)
   {}

   //!makes a named allocation and calls the
   //!default constructor
   T *operator()() const
   {  
      Ctor0Arg<T> ctor_obj;
      return mp_mngr->template 
         generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
   }
   //!

   #define BOOST_PP_LOCAL_MACRO(n)                                               \
      template<BOOST_PP_ENUM_PARAMS(n, class P)>                                 \
      T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) const\
      {                                                                          \
         typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg)                        \
            <T, is_iterator, BOOST_PP_ENUM_PARAMS(n, P)>                         \
            ctor_obj_t;                                                          \
         ctor_obj_t ctor_obj                                                     \
            (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));          \
         return mp_mngr->template generic_construct<T>                           \
            (mp_name, m_num, m_find, m_dothrow, ctor_obj);                       \
      }                                                                          \
   //!

   #define BOOST_PP_LOCAL_LIMITS ( 1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS )
   #include BOOST_PP_LOCAL_ITERATE()

   ////////////////////////////////////////////////////////////////////////
   //             What the macro should generate (n == 2)
   ////////////////////////////////////////////////////////////////////////
   //
   // template <class P1, class P2>
   // T *operator()(P1 &p1, P2 &p2) const 
   // {
   //    typedef Ctor2Arg
   //       <T, is_iterator, P1, P2>
   //       ctor_obj_t;
   //    ctor_obj_t ctor_obj(p1, p2);
   //
   //    return mp_mngr->template generic_construct<T>
   //       (mp_name, m_num, m_find, m_dothrow, ctor_obj);
   // }
   //
   //////////////////////////////////////////////////////////////////////////

   //This operator allows --> named_new("Name")[3]; <-- syntax
   const named_proxy &operator[](std::size_t num) const
      {  m_num *= num; return *this;  }
};

#endif   //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING

}}}   //namespace boost { namespace interprocess { namespace detail {

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

#endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
