////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2012. 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 #ifndef BOOST_CONFIG_HPP # include #endif # #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include #include // interprocess/detail #include #include #include #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING #include #else #include #include #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING #include //!\file //!Describes a proxy class that implements named allocation syntax. namespace boost { namespace interprocess { namespace ipcdetail { #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING template struct CtorArgN : public placement_destroy { typedef bool_ IsIterator; typedef CtorArgN self_t; typedef typename build_number_seq::type index_tuple_t; self_t& operator++() { this->do_increment(IsIterator(), index_tuple_t()); return *this; } self_t operator++(int) { return ++*this; *this; } CtorArgN(Args && ...args) : args_(args...) {} virtual void construct_n(void *mem , std::size_t num , std::size_t &constructed) { T* memory = static_cast(mem); for(constructed = 0; constructed < num; ++constructed){ this->construct(memory++, IsIterator(), index_tuple_t()); this->do_increment(IsIterator(), index_tuple_t()); } } private: template void construct(void *mem, true_, const index_tuple&) { ::new((void*)mem, boost_container_new_t())T(*boost::forward(get(args_))...); } template void construct(void *mem, false_, const index_tuple&) { ::new((void*)mem, boost_container_new_t())T(boost::forward(get(args_))...); } template void do_increment(true_, const index_tuple&) { this->expansion_helper(++get(args_)...); } template void expansion_helper(ExpansionArgs &&...) {} template void do_increment(false_, const index_tuple&) {} tuple 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 T *operator()(Args &&...args) const { CtorArgN &&ctor_obj = CtorArgN (boost::forward(args)...); return mp_mngr->template generic_construct(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 //////////////////////////////////////////////////////////////// // What the macro should generate (n == 2): // // template // struct Ctor2Arg // : public placement_destroy // { // typedef bool_ IsIterator; // typedef Ctor2Arg self_t; // // void do_increment(false_) // { ++m_p1; ++m_p2; } // // void do_increment(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(mem); // for(constructed = 0; constructed < num; ++constructed){ // this->construct(memory++, IsIterator()); // this->do_increment(IsIterator()); // } // } // // private: // void construct(void *mem, true_) // { new((void*)mem)T(*m_p1, *m_p2); } // // void construct(void *mem, false_) // { new((void*)mem)T(m_p1, m_p2); } // // P1 &m_p1; P2 &m_p2; // }; //////////////////////////////////////////////////////////////// #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\ \ template \ struct CtorArg##N : placement_destroy\ {\ typedef CtorArg##N self_t;\ \ CtorArg##N ( BOOST_MOVE_UREF##N )\ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ \ virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\ {\ T* memory = static_cast(mem);\ for(constructed = 0; constructed < num; ++constructed){\ ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\ }\ }\ \ private:\ BOOST_MOVE_MREF##N\ };\ //! BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN) #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\ \ template \ struct CtorIt##N : public placement_destroy\ {\ typedef CtorIt##N self_t;\ \ self_t& operator++()\ { BOOST_MOVE_MINC##N; return *this; }\ \ self_t operator++(int) { return ++*this; *this; }\ \ CtorIt##N ( BOOST_MOVE_VAL##N )\ BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\ \ virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\ {\ T* memory = static_cast(mem);\ for(constructed = 0; constructed < num; ++constructed){\ ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\ ++(*this);\ }\ }\ \ private:\ BOOST_MOVE_MEMB##N\ };\ //! BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN) #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN //!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) {} #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\ \ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ T *operator()( BOOST_MOVE_UREF##N ) const\ {\ typedef typename if_c \ , CtorArg##N \ >::type ctor_obj_t;\ ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\ return mp_mngr->template generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj);\ }\ // BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR) #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR //////////////////////////////////////////////////////////////////////// // What the macro should generate (n == 2) //////////////////////////////////////////////////////////////////////// // // template // T *operator()(P1 &p1, P2 &p2) const // { // typedef CtorArg2 // // ctor_obj_t; // ctor_obj_t ctor_obj(p1, p2); // // return mp_mngr->template generic_construct // (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 ipcdetail { #include #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP