Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP Chris@16: #define BOOST_INTERPROCESS_NAMED_PROXY_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@101: // interprocess/detail Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING Chris@101: #include Chris@16: #else Chris@101: #include Chris@16: #include Chris@16: #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING Chris@101: #include Chris@16: Chris@16: //!\file Chris@16: //!Describes a proxy class that implements named allocation syntax. Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: namespace ipcdetail { Chris@16: Chris@16: #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING Chris@16: Chris@16: template Chris@101: struct CtorArgN : public placement_destroy Chris@16: { Chris@16: typedef bool_ IsIterator; Chris@101: typedef CtorArgN self_t; Chris@16: typedef typename build_number_seq::type index_tuple_t; Chris@16: Chris@16: self_t& operator++() Chris@16: { Chris@16: this->do_increment(IsIterator(), index_tuple_t()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: self_t operator++(int) { return ++*this; *this; } Chris@16: Chris@101: CtorArgN(Args && ...args) Chris@16: : args_(args...) Chris@16: {} Chris@16: Chris@16: virtual void construct_n(void *mem Chris@16: , std::size_t num Chris@16: , std::size_t &constructed) Chris@16: { Chris@16: T* memory = static_cast(mem); Chris@16: for(constructed = 0; constructed < num; ++constructed){ Chris@16: this->construct(memory++, IsIterator(), index_tuple_t()); Chris@16: this->do_increment(IsIterator(), index_tuple_t()); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: template Chris@16: void construct(void *mem, true_, const index_tuple&) Chris@101: { ::new((void*)mem, boost_container_new_t())T(*boost::forward(get(args_))...); } Chris@16: Chris@16: template Chris@16: void construct(void *mem, false_, const index_tuple&) Chris@101: { ::new((void*)mem, boost_container_new_t())T(boost::forward(get(args_))...); } Chris@16: Chris@16: template Chris@16: void do_increment(true_, const index_tuple&) Chris@16: { Chris@16: this->expansion_helper(++get(args_)...); Chris@16: } Chris@16: Chris@16: template Chris@16: void expansion_helper(ExpansionArgs &&...) Chris@16: {} Chris@16: Chris@16: template Chris@16: void do_increment(false_, const index_tuple&) Chris@16: {} Chris@16: Chris@16: tuple args_; Chris@16: }; Chris@16: Chris@16: //!Describes a proxy class that implements named Chris@16: //!allocation syntax. Chris@16: template Chris@16: < class SegmentManager //segment manager to construct the object Chris@16: , class T //type of object to build Chris@16: , bool is_iterator //passing parameters are normal object or iterators? Chris@16: > Chris@16: class named_proxy Chris@16: { Chris@16: typedef typename SegmentManager::char_type char_type; Chris@16: const char_type * mp_name; Chris@16: SegmentManager * mp_mngr; Chris@16: mutable std::size_t m_num; Chris@16: const bool m_find; Chris@16: const bool m_dothrow; Chris@16: Chris@16: public: Chris@16: named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow) Chris@16: : mp_name(name), mp_mngr(mngr), m_num(1) Chris@16: , m_find(find), m_dothrow(dothrow) Chris@16: {} Chris@16: Chris@16: template Chris@16: T *operator()(Args &&...args) const Chris@16: { Chris@101: CtorArgN &&ctor_obj = CtorArgN Chris@16: (boost::forward(args)...); Chris@16: return mp_mngr->template Chris@16: generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj); Chris@16: } Chris@16: Chris@16: //This operator allows --> named_new("Name")[3]; <-- syntax Chris@16: const named_proxy &operator[](std::size_t num) const Chris@16: { m_num *= num; return *this; } Chris@16: }; Chris@16: Chris@16: #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING Chris@16: Chris@16: //////////////////////////////////////////////////////////////// Chris@16: // What the macro should generate (n == 2): Chris@16: // Chris@16: // template Chris@16: // struct Ctor2Arg Chris@16: // : public placement_destroy Chris@16: // { Chris@16: // typedef bool_ IsIterator; Chris@16: // typedef Ctor2Arg self_t; Chris@16: // Chris@16: // void do_increment(false_) Chris@16: // { ++m_p1; ++m_p2; } Chris@16: // Chris@16: // void do_increment(true_){} Chris@16: // Chris@16: // self_t& operator++() Chris@16: // { Chris@16: // this->do_increment(IsIterator()); Chris@16: // return *this; Chris@16: // } Chris@16: // Chris@16: // self_t operator++(int) { return ++*this; *this; } Chris@16: // Chris@16: // Ctor2Arg(const P1 &p1, const P2 &p2) Chris@16: // : p1((P1 &)p_1), p2((P2 &)p_2) {} Chris@16: // Chris@16: // void construct(void *mem) Chris@16: // { new((void*)object)T(m_p1, m_p2); } Chris@16: // Chris@16: // virtual void construct_n(void *mem Chris@16: // , std::size_t num Chris@16: // , std::size_t &constructed) Chris@16: // { Chris@16: // T* memory = static_cast(mem); Chris@16: // for(constructed = 0; constructed < num; ++constructed){ Chris@16: // this->construct(memory++, IsIterator()); Chris@16: // this->do_increment(IsIterator()); Chris@16: // } Chris@16: // } Chris@16: // Chris@16: // private: Chris@16: // void construct(void *mem, true_) Chris@16: // { new((void*)mem)T(*m_p1, *m_p2); } Chris@16: // Chris@16: // void construct(void *mem, false_) Chris@16: // { new((void*)mem)T(m_p1, m_p2); } Chris@16: // Chris@16: // P1 &m_p1; P2 &m_p2; Chris@16: // }; Chris@16: //////////////////////////////////////////////////////////////// Chris@16: Chris@101: #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\ Chris@101: \ Chris@101: template \ Chris@101: struct CtorArg##N : placement_destroy\ Chris@101: {\ Chris@101: typedef CtorArg##N self_t;\ Chris@101: \ Chris@101: CtorArg##N ( BOOST_MOVE_UREF##N )\ Chris@101: BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ Chris@101: \ Chris@101: virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\ Chris@101: {\ Chris@101: T* memory = static_cast(mem);\ Chris@101: for(constructed = 0; constructed < num; ++constructed){\ Chris@101: ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\ Chris@101: }\ Chris@101: }\ Chris@101: \ Chris@101: private:\ Chris@101: BOOST_MOVE_MREF##N\ Chris@101: };\ Chris@16: //! Chris@101: BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN) Chris@101: #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN Chris@101: Chris@101: #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\ Chris@101: \ Chris@101: template \ Chris@101: struct CtorIt##N : public placement_destroy\ Chris@101: {\ Chris@101: typedef CtorIt##N self_t;\ Chris@101: \ Chris@101: self_t& operator++()\ Chris@101: { BOOST_MOVE_MINC##N; return *this; }\ Chris@101: \ Chris@101: self_t operator++(int) { return ++*this; *this; }\ Chris@101: \ Chris@101: CtorIt##N ( BOOST_MOVE_VAL##N )\ Chris@101: BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\ Chris@101: \ Chris@101: virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)\ Chris@101: {\ Chris@101: T* memory = static_cast(mem);\ Chris@101: for(constructed = 0; constructed < num; ++constructed){\ Chris@101: ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\ Chris@101: ++(*this);\ Chris@101: }\ Chris@101: }\ Chris@101: \ Chris@101: private:\ Chris@101: BOOST_MOVE_MEMB##N\ Chris@101: };\ Chris@101: //! Chris@101: BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN) Chris@101: #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN Chris@16: Chris@16: //!Describes a proxy class that implements named Chris@16: //!allocation syntax. Chris@16: template Chris@16: < class SegmentManager //segment manager to construct the object Chris@16: , class T //type of object to build Chris@16: , bool is_iterator //passing parameters are normal object or iterators? Chris@16: > Chris@16: class named_proxy Chris@16: { Chris@16: typedef typename SegmentManager::char_type char_type; Chris@16: const char_type * mp_name; Chris@16: SegmentManager * mp_mngr; Chris@16: mutable std::size_t m_num; Chris@16: const bool m_find; Chris@16: const bool m_dothrow; Chris@16: Chris@16: public: Chris@16: named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow) Chris@16: : mp_name(name), mp_mngr(mngr), m_num(1) Chris@16: , m_find(find), m_dothrow(dothrow) Chris@16: {} Chris@16: Chris@101: #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\ Chris@101: \ Chris@101: BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ Chris@101: T *operator()( BOOST_MOVE_UREF##N ) const\ Chris@101: {\ Chris@101: typedef typename if_c \ Chris@101: , CtorArg##N \ Chris@101: >::type ctor_obj_t;\ Chris@101: ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\ Chris@101: return mp_mngr->template generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj);\ Chris@101: }\ Chris@101: // Chris@101: BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR) Chris@101: #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: // What the macro should generate (n == 2) Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // template Chris@16: // T *operator()(P1 &p1, P2 &p2) const Chris@16: // { Chris@101: // typedef CtorArg2 Chris@16: // Chris@16: // ctor_obj_t; Chris@16: // ctor_obj_t ctor_obj(p1, p2); Chris@16: // Chris@16: // return mp_mngr->template generic_construct Chris@16: // (mp_name, m_num, m_find, m_dothrow, ctor_obj); Chris@16: // } Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: //This operator allows --> named_new("Name")[3]; <-- syntax Chris@16: const named_proxy &operator[](std::size_t num) const Chris@16: { m_num *= num; return *this; } Chris@16: }; Chris@16: Chris@16: #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING Chris@16: Chris@16: }}} //namespace boost { namespace interprocess { namespace ipcdetail { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP