named_proxy.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 349 行
HPP
349 行
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2008. 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_FORWARDINGtemplate<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(*detail::forward_impl<Args>(get<IdxPack>(args_))...); } template<int ...IdxPack> void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&) { new((void*)mem)T(detail::forward_impl<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(detail::forward_impl<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 argumentstemplate<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 rvalues 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?