File indexing completed on 2025-07-01 08:18:02
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/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
0035 #include <boost/container/detail/placement_new.hpp>
0036
0037 #include <cstddef>
0038
0039
0040
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, std::size_t num) BOOST_OVERRIDE
0068 {
0069 std::size_t constructed = 0;
0070 BOOST_TRY{
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 BOOST_CATCH(...) {
0078 this->placement_destroy<T>::destroy_n(mem, constructed);
0079 BOOST_RETHROW
0080 } BOOST_CATCH_END
0081 }
0082
0083 private:
0084 template<std::size_t ...IdxPack>
0085 void construct(void *mem, true_, const index_tuple<IdxPack...>&)
0086 { ::new((void*)mem, boost_container_new_t())T(*boost::forward<Args>((get<IdxPack>)(args_))...); }
0087
0088 template<std::size_t ...IdxPack>
0089 void construct(void *mem, false_, const index_tuple<IdxPack...>&)
0090 { ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>((get<IdxPack>)(args_))...); }
0091
0092 template<std::size_t ...IdxPack>
0093 void do_increment(true_, const index_tuple<IdxPack...>&)
0094 {
0095 this->expansion_helper(++(get<IdxPack>)(args_)...);
0096 }
0097
0098 template<class ...ExpansionArgs>
0099 void expansion_helper(ExpansionArgs &&...)
0100 {}
0101
0102 template<std::size_t ...IdxPack>
0103 void do_increment(false_, const index_tuple<IdxPack...>&)
0104 {}
0105
0106 tuple<Args&...> args_;
0107 };
0108
0109
0110
0111 template
0112 < class SegmentManager
0113 , class T
0114 , bool is_iterator
0115 >
0116 class named_proxy
0117 {
0118 typedef typename SegmentManager::char_type char_type;
0119 const char_type * mp_name;
0120 SegmentManager * mp_mngr;
0121 mutable std::size_t m_num;
0122 const bool m_find;
0123 const bool m_dothrow;
0124
0125 public:
0126 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
0127 : mp_name(name), mp_mngr(mngr), m_num(1)
0128 , m_find(find), m_dothrow(dothrow)
0129 {}
0130
0131 template<class ...Args>
0132 T *operator()(Args &&...args) const
0133 {
0134 CtorArgN<T, is_iterator, Args...> &&ctor_obj = CtorArgN<T, is_iterator, Args...>
0135 (boost::forward<Args>(args)...);
0136 return mp_mngr->template
0137 generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
0138 }
0139
0140
0141 const named_proxy &operator[](std::size_t num) const
0142 { m_num *= num; return *this; }
0143 };
0144
0145 #else
0146
0147 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN(N)\
0148 \
0149 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
0150 struct CtorArg##N : placement_destroy<T>\
0151 {\
0152 typedef CtorArg##N self_t;\
0153 \
0154 CtorArg##N ( BOOST_MOVE_UREF##N )\
0155 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
0156 \
0157 virtual void construct_n(void *mem, std::size_t num) BOOST_OVERRIDE\
0158 {\
0159 std::size_t constructed = 0;\
0160 BOOST_TRY{\
0161 T* memory = static_cast<T*>(mem);\
0162 for (constructed = 0; constructed < num; ++constructed) {\
0163 ::new((void*)memory++) T ( BOOST_MOVE_MFWD##N );\
0164 }\
0165 }\
0166 BOOST_CATCH(...) {\
0167 this->placement_destroy<T>::destroy_n(mem, constructed);\
0168 BOOST_RETHROW\
0169 } BOOST_CATCH_END\
0170 }\
0171 \
0172 private:\
0173 BOOST_MOVE_MREF##N\
0174 };\
0175
0176 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN)
0177 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN
0178
0179 #define BOOST_INTERPROCESS_NAMED_PROXY_CTORITN(N)\
0180 \
0181 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
0182 struct CtorIt##N : public placement_destroy<T>\
0183 {\
0184 typedef CtorIt##N self_t;\
0185 \
0186 self_t& operator++()\
0187 { BOOST_MOVE_MINC##N; return *this; }\
0188 \
0189 self_t operator++(int) { return ++*this; *this; }\
0190 \
0191 CtorIt##N ( BOOST_MOVE_VAL##N )\
0192 BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\
0193 \
0194 virtual void construct_n(void *mem, std::size_t num) BOOST_OVERRIDE\
0195 {\
0196 std::size_t constructed = 0;\
0197 BOOST_TRY{\
0198 T* memory = static_cast<T*>(mem);\
0199 for(constructed = 0; constructed < num; ++constructed){\
0200 ::new((void*)memory++) T( BOOST_MOVE_MITFWD##N );\
0201 ++(*this);\
0202 }\
0203 }\
0204 BOOST_CATCH(...) {\
0205 this->placement_destroy<T>::destroy_n(mem, constructed);\
0206 BOOST_RETHROW\
0207 } BOOST_CATCH_END\
0208 }\
0209 \
0210 private:\
0211 BOOST_MOVE_MEMB##N\
0212 };\
0213
0214 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORITN)
0215 #undef BOOST_INTERPROCESS_NAMED_PROXY_CTORITN
0216
0217
0218
0219 template
0220 < class SegmentManager
0221 , class T
0222 , bool is_iterator
0223 >
0224 class named_proxy
0225 {
0226 typedef typename SegmentManager::char_type char_type;
0227 const char_type * mp_name;
0228 SegmentManager * mp_mngr;
0229 mutable std::size_t m_num;
0230 const bool m_find;
0231 const bool m_dothrow;
0232
0233 public:
0234 named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
0235 : mp_name(name), mp_mngr(mngr), m_num(1)
0236 , m_find(find), m_dothrow(dothrow)
0237 {}
0238
0239 #define BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR(N)\
0240 \
0241 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
0242 T *operator()( BOOST_MOVE_UREF##N ) const\
0243 {\
0244 typedef typename if_c<is_iterator \
0245 , CtorIt##N <T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
0246 , CtorArg##N<T BOOST_MOVE_I##N BOOST_MOVE_TARG##N> \
0247 >::type ctor_obj_t;\
0248 ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\
0249 return mp_mngr->template generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);\
0250 }\
0251
0252 BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR)
0253 #undef BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 const named_proxy &operator[](std::size_t num) const
0275 { m_num *= num; return *this; }
0276 };
0277
0278 #endif
0279
0280 }}}
0281
0282 #include <boost/interprocess/detail/config_end.hpp>
0283
0284 #endif