Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:26

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP
0012 #define BOOST_INTERPROCESS_NAMED_PROXY_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 
0025 // interprocess/detail
0026 #include <boost/interprocess/detail/in_place_interface.hpp>
0027 #include <boost/interprocess/detail/mpl.hpp>
0028 #include <boost/move/utility_core.hpp>
0029 #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
0030 #include <boost/move/detail/fwd_macros.hpp>
0031 #else
0032 #include <boost/move/utility_core.hpp>
0033 #include <boost/interprocess/detail/variadic_templates_tools.hpp>
0034 #endif   //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
0035 #include <boost/container/detail/placement_new.hpp>
0036 
0037 #include <cstddef>
0038 
0039 //!\file
0040 //!Describes a proxy class that implements named allocation syntax.
0041 
0042 namespace boost {
0043 namespace interprocess {
0044 namespace ipcdetail {
0045 
0046 #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
0047 
0048 template<class T, bool is_iterator, class ...Args>
0049 struct CtorArgN : public placement_destroy<T>
0050 {
0051    typedef bool_<is_iterator> IsIterator;
0052    typedef CtorArgN<T, is_iterator, Args...> self_t;
0053    typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
0054 
0055    self_t& operator++()
0056    {
0057       this->do_increment(IsIterator(), index_tuple_t());
0058       return *this;
0059    }
0060 
0061    self_t  operator++(int) {  return ++*this;   *this;  }
0062 
0063    CtorArgN(Args && ...args)
0064       :  args_(args...)
0065    {}
0066 
0067    virtual void construct_n(void *mem
0068                      , std::size_t num
0069                      , std::size_t &constructed) BOOST_OVERRIDE
0070    {
0071       T* memory      = static_cast<T*>(mem);
0072       for(constructed = 0; constructed < num; ++constructed){
0073          this->construct(memory++, IsIterator(), index_tuple_t());
0074          this->do_increment(IsIterator(), index_tuple_t());
0075       }
0076    }
0077 
0078    private:
0079    template<std::size_t ...IdxPack>
0080    void construct(void *mem, true_, const index_tuple<IdxPack...>&)
0081    {  ::new((void*)mem, boost_container_new_t())T(*boost::forward<Args>(get<IdxPack>(args_))...); }
0082 
0083    template<std::size_t ...IdxPack>
0084    void construct(void *mem, false_, const index_tuple<IdxPack...>&)
0085    {  ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>(get<IdxPack>(args_))...); }
0086 
0087    template<std::size_t ...IdxPack>
0088    void do_increment(true_, const index_tuple<IdxPack...>&)
0089    {
0090       this->expansion_helper(++get<IdxPack>(args_)...);
0091    }
0092 
0093    template<class ...ExpansionArgs>
0094    void expansion_helper(ExpansionArgs &&...)
0095    {}
0096 
0097    template<std::size_t ...IdxPack>
0098    void do_increment(false_, const index_tuple<IdxPack...>&)
0099    {}
0100 
0101    tuple<Args&...> args_;
0102 };
0103 
0104 //!Describes a proxy class that implements named
0105 //!allocation syntax.
0106 template
0107    < class SegmentManager  //segment manager to construct the object
0108    , class T               //type of object to build
0109    , bool is_iterator      //passing parameters are normal object or iterators?
0110    >
0111 class named_proxy
0112 {
0113    typedef typename SegmentManager::char_type char_type;
0114    const char_type *    mp_name;
0115    SegmentManager *     mp_mngr;
0116    mutable std::size_t  m_num;
0117    const bool           m_find;
0118    const bool           m_dothrow;
0119 
0120    public:
0121    named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
0122       :  mp_name(name), mp_mngr(mngr), m_num(1)
0123       ,  m_find(find),  m_dothrow(dothrow)
0124    {}
0125 
0126    template<class ...Args>
0127    T *operator()(Args &&...args) const
0128    {
0129       CtorArgN<T, is_iterator, Args...> &&ctor_obj = CtorArgN<T, is_iterator, Args...>
0130          (boost::forward<Args>(args)...);
0131       return mp_mngr->template
0132          generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
0133    }
0134 
0135    //This operator allows --> named_new("Name")[3]; <-- syntax
0136    const named_proxy &operator[](std::size_t num) const
0137    {  m_num *= num; return *this;  }
0138 };
0139 
0140 #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
0141 
0142 ////////////////////////////////////////////////////////////////
0143 //    What the macro should generate (n == 2):
0144 //
0145 //    template<class T, bool is_iterator, class P1, class P2>
0146 //    struct Ctor2Arg
0147 //      :  public placement_destroy<T>
0148 //    {
0149 //       typedef bool_<is_iterator> IsIterator;
0150 //       typedef Ctor2Arg self_t;
0151 //
0152 //       void do_increment(false_)
0153 //       { ++m_p1; ++m_p2;  }
0154 //
0155 //       void do_increment(true_){}
0156 //
0157 //       self_t& operator++()
0158 //       {
0159 //          this->do_increment(IsIterator());
0160 //          return *this;
0161 //       }
0162 //
0163 //       self_t  operator++(int) {  return ++*this;   *this;  }
0164 //
0165 //       Ctor2Arg(const P1 &p1, const P2 &p2)
0166 //          : p1((P1 &)p_1), p2((P2 &)p_2) {}
0167 //
0168 //       void construct(void *mem)
0169 //       {  new((void*)object)T(m_p1, m_p2); }
0170 //
0171 //       virtual void construct_n(void *mem
0172 //                                , std::size_t num
0173 //                                , std::size_t &constructed)
0174 //       {
0175 //          T* memory      = static_cast<T*>(mem);
0176 //          for(constructed = 0; constructed < num; ++constructed){
0177 //             this->construct(memory++, IsIterator());
0178 //             this->do_increment(IsIterator());
0179 //          }
0180 //       }
0181 //
0182 //       private:
0183 //       void construct(void *mem, true_)
0184 //       {  new((void*)mem)T(*m_p1, *m_p2); }
0185 //
0186 //       void construct(void *mem, false_)
0187 //       {  new((void*)mem)T(m_p1, m_p2); }
0188 //
0189 //       P1 &m_p1; P2 &m_p2;
0190 //    };
0191 ////////////////////////////////////////////////////////////////
0192 
0193 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\
0194 \
0195 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >  \
0196 struct CtorArg##N : placement_destroy<T>\
0197 {\
0198    typedef CtorArg##N self_t;\
0199    \
0200    CtorArg##N ( BOOST_MOVE_UREF##N  )\
0201       BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
0202    \
0203    virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) BOOST_OVERRIDE\
0204    {\
0205       T* memory      = static_cast<T*>(mem);\
0206       for(constructed = 0; constructed < num; ++constructed){\
0207          ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\
0208       }\
0209    }\
0210    \
0211    private:\
0212    BOOST_MOVE_MREF##N\
0213 };\
0214 //!
0215 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN)
0216 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN
0217 
0218 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\
0219 \
0220 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
0221 struct CtorIt##N : public placement_destroy<T>\
0222 {\
0223    typedef CtorIt##N self_t;\
0224    \
0225    self_t& operator++()\
0226    {  BOOST_MOVE_MINC##N;  return *this;  }\
0227    \
0228    self_t  operator++(int) {  return ++*this; *this;  }\
0229    \
0230    CtorIt##N ( BOOST_MOVE_VAL##N  )\
0231       BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\
0232    \
0233    virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) BOOST_OVERRIDE\
0234    {\
0235       T* memory      = static_cast<T*>(mem);\
0236       for(constructed = 0; constructed < num; ++constructed){\
0237          ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\
0238          ++(*this);\
0239       }\
0240    }\
0241    \
0242    private:\
0243    BOOST_MOVE_MEMB##N\
0244 };\
0245 //!
0246 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN)
0247 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN
0248 
0249 //!Describes a proxy class that implements named
0250 //!allocation syntax.
0251 template
0252    < class SegmentManager  //segment manager to construct the object
0253    , class T               //type of object to build
0254    , bool is_iterator      //passing parameters are normal object or iterators?
0255    >
0256 class named_proxy
0257 {
0258    typedef typename SegmentManager::char_type char_type;
0259    const char_type *    mp_name;
0260    SegmentManager *     mp_mngr;
0261    mutable std::size_t  m_num;
0262    const bool           m_find;
0263    const bool           m_dothrow;
0264 
0265    public:
0266    named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
0267       :  mp_name(name), mp_mngr(mngr), m_num(1)
0268       ,  m_find(find),  m_dothrow(dothrow)
0269    {}
0270 
0271    #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\
0272    \
0273    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0274    T *operator()( BOOST_MOVE_UREF##N ) const\
0275    {\
0276       typedef typename if_c<is_iterator \
0277          , CtorIt##N <T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
0278          , CtorArg##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
0279          >::type ctor_obj_t;\
0280       ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\
0281       return mp_mngr->template generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);\
0282    }\
0283    //
0284    BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR)
0285    #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR
0286 
0287    ////////////////////////////////////////////////////////////////////////
0288    //             What the macro should generate (n == 2)
0289    ////////////////////////////////////////////////////////////////////////
0290    //
0291    // template <class P1, class P2>
0292    // T *operator()(P1 &p1, P2 &p2) const
0293    // {
0294    //    typedef CtorArg2
0295    //       <T, is_iterator, P1, P2>
0296    //       ctor_obj_t;
0297    //    ctor_obj_t ctor_obj(p1, p2);
0298    //
0299    //    return mp_mngr->template generic_construct<T>
0300    //       (mp_name, m_num, m_find, m_dothrow, ctor_obj);
0301    // }
0302    //
0303    //////////////////////////////////////////////////////////////////////////
0304 
0305    //This operator allows --> named_new("Name")[3]; <-- syntax
0306    const named_proxy &operator[](std::size_t num) const
0307       {  m_num *= num; return *this;  }
0308 };
0309 
0310 #endif   //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
0311 
0312 }}}   //namespace boost { namespace interprocess { namespace ipcdetail {
0313 
0314 #include <boost/interprocess/detail/config_end.hpp>
0315 
0316 #endif //#ifndef BOOST_INTERPROCESS_NAMED_PROXY_HPP