File indexing completed on 2025-09-18 08:46:51
0001
0002
0003
0004
0005
0006
0007
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
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
0034 #include <boost/container/detail/placement_new.hpp>
0035
0036 #include <cstddef>
0037
0038
0039
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
0119
0120 template
0121 < class SegmentManager
0122 , class T
0123 , bool is_iterator
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
0149 const named_proxy &operator[](std::size_t num) const
0150 { m_num *= num; return *this; }
0151 };
0152
0153 #else
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
0228
0229 template
0230 < class SegmentManager
0231 , class T
0232 , bool is_iterator
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
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 const named_proxy &operator[](std::size_t num) const
0285 { m_num *= num; return *this; }
0286 };
0287
0288 #endif
0289
0290 }}}
0291
0292 #include <boost/interprocess/detail/config_end.hpp>
0293
0294 #endif