Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:46:51

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