////////////////////////////////////////////////////////////////////////////// // // (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 #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) BOOST_OVERRIDE { std::size_t constructed = 0; BOOST_TRY{ 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()); } } BOOST_CATCH(...) { this->placement_destroy::destroy_n(mem, constructed); BOOST_RETHROW } BOOST_CATCH_END } 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 #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) BOOST_OVERRIDE\ {\ std::size_t constructed = 0;\ BOOST_TRY{\ T* memory = static_cast(mem);\ for (constructed = 0; constructed < num; ++constructed) {\ ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\ }\ }\ BOOST_CATCH(...) {\ this->placement_destroy::destroy_n(mem, constructed);\ BOOST_RETHROW\ } BOOST_CATCH_END\ }\ \ 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) BOOST_OVERRIDE\ {\ std::size_t constructed = 0;\ BOOST_TRY{\ T* memory = static_cast(mem);\ for(constructed = 0; constructed < num; ++constructed){\ ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\ ++(*this);\ }\ }\ BOOST_CATCH(...) {\ this->placement_destroy::destroy_n(mem, constructed);\ BOOST_RETHROW\ } BOOST_CATCH_END\ }\ \ 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