Warning, file /include/boost/asio/bind_allocator.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_BIND_ALLOCATOR_HPP
0012 #define BOOST_ASIO_BIND_ALLOCATOR_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/associated_allocator.hpp>
0020 #include <boost/asio/associated_executor.hpp>
0021 #include <boost/asio/associator.hpp>
0022 #include <boost/asio/async_result.hpp>
0023 #include <boost/asio/detail/initiation_base.hpp>
0024 #include <boost/asio/detail/type_traits.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031
0032
0033
0034 template <typename T, typename = void>
0035 struct allocator_binder_result_type
0036 {
0037 protected:
0038 typedef void result_type_or_void;
0039 };
0040
0041 template <typename T>
0042 struct allocator_binder_result_type<T, void_t<typename T::result_type>>
0043 {
0044 typedef typename T::result_type result_type;
0045 protected:
0046 typedef result_type result_type_or_void;
0047 };
0048
0049 template <typename R>
0050 struct allocator_binder_result_type<R(*)()>
0051 {
0052 typedef R result_type;
0053 protected:
0054 typedef result_type result_type_or_void;
0055 };
0056
0057 template <typename R>
0058 struct allocator_binder_result_type<R(&)()>
0059 {
0060 typedef R result_type;
0061 protected:
0062 typedef result_type result_type_or_void;
0063 };
0064
0065 template <typename R, typename A1>
0066 struct allocator_binder_result_type<R(*)(A1)>
0067 {
0068 typedef R result_type;
0069 protected:
0070 typedef result_type result_type_or_void;
0071 };
0072
0073 template <typename R, typename A1>
0074 struct allocator_binder_result_type<R(&)(A1)>
0075 {
0076 typedef R result_type;
0077 protected:
0078 typedef result_type result_type_or_void;
0079 };
0080
0081 template <typename R, typename A1, typename A2>
0082 struct allocator_binder_result_type<R(*)(A1, A2)>
0083 {
0084 typedef R result_type;
0085 protected:
0086 typedef result_type result_type_or_void;
0087 };
0088
0089 template <typename R, typename A1, typename A2>
0090 struct allocator_binder_result_type<R(&)(A1, A2)>
0091 {
0092 typedef R result_type;
0093 protected:
0094 typedef result_type result_type_or_void;
0095 };
0096
0097
0098
0099 template <typename T, typename = void>
0100 struct allocator_binder_argument_type {};
0101
0102 template <typename T>
0103 struct allocator_binder_argument_type<T, void_t<typename T::argument_type>>
0104 {
0105 typedef typename T::argument_type argument_type;
0106 };
0107
0108 template <typename R, typename A1>
0109 struct allocator_binder_argument_type<R(*)(A1)>
0110 {
0111 typedef A1 argument_type;
0112 };
0113
0114 template <typename R, typename A1>
0115 struct allocator_binder_argument_type<R(&)(A1)>
0116 {
0117 typedef A1 argument_type;
0118 };
0119
0120
0121
0122
0123 template <typename T, typename = void>
0124 struct allocator_binder_argument_types {};
0125
0126 template <typename T>
0127 struct allocator_binder_argument_types<T,
0128 void_t<typename T::first_argument_type>>
0129 {
0130 typedef typename T::first_argument_type first_argument_type;
0131 typedef typename T::second_argument_type second_argument_type;
0132 };
0133
0134 template <typename R, typename A1, typename A2>
0135 struct allocator_binder_argument_type<R(*)(A1, A2)>
0136 {
0137 typedef A1 first_argument_type;
0138 typedef A2 second_argument_type;
0139 };
0140
0141 template <typename R, typename A1, typename A2>
0142 struct allocator_binder_argument_type<R(&)(A1, A2)>
0143 {
0144 typedef A1 first_argument_type;
0145 typedef A2 second_argument_type;
0146 };
0147
0148 }
0149
0150
0151
0152 template <typename T, typename Allocator>
0153 class allocator_binder
0154 #if !defined(GENERATING_DOCUMENTATION)
0155 : public detail::allocator_binder_result_type<T>,
0156 public detail::allocator_binder_argument_type<T>,
0157 public detail::allocator_binder_argument_types<T>
0158 #endif
0159 {
0160 public:
0161
0162 typedef T target_type;
0163
0164
0165 typedef Allocator allocator_type;
0166
0167 #if defined(GENERATING_DOCUMENTATION)
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 typedef see_below result_type;
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 typedef see_below argument_type;
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 typedef see_below first_argument_type;
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 typedef see_below second_argument_type;
0227 #endif
0228
0229
0230
0231
0232
0233
0234 template <typename U>
0235 allocator_binder(const allocator_type& s, U&& u)
0236 : allocator_(s),
0237 target_(static_cast<U&&>(u))
0238 {
0239 }
0240
0241
0242 allocator_binder(const allocator_binder& other)
0243 : allocator_(other.get_allocator()),
0244 target_(other.get())
0245 {
0246 }
0247
0248
0249 allocator_binder(const allocator_type& s, const allocator_binder& other)
0250 : allocator_(s),
0251 target_(other.get())
0252 {
0253 }
0254
0255
0256
0257
0258
0259
0260
0261 template <typename U, typename OtherAllocator>
0262 allocator_binder(const allocator_binder<U, OtherAllocator>& other,
0263 constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,
0264 constraint_t<is_constructible<T, U>::value> = 0)
0265 : allocator_(other.get_allocator()),
0266 target_(other.get())
0267 {
0268 }
0269
0270
0271
0272
0273
0274
0275
0276 template <typename U, typename OtherAllocator>
0277 allocator_binder(const allocator_type& s,
0278 const allocator_binder<U, OtherAllocator>& other,
0279 constraint_t<is_constructible<T, U>::value> = 0)
0280 : allocator_(s),
0281 target_(other.get())
0282 {
0283 }
0284
0285
0286 allocator_binder(allocator_binder&& other)
0287 : allocator_(static_cast<allocator_type&&>(
0288 other.get_allocator())),
0289 target_(static_cast<T&&>(other.get()))
0290 {
0291 }
0292
0293
0294 allocator_binder(const allocator_type& s,
0295 allocator_binder&& other)
0296 : allocator_(s),
0297 target_(static_cast<T&&>(other.get()))
0298 {
0299 }
0300
0301
0302 template <typename U, typename OtherAllocator>
0303 allocator_binder(
0304 allocator_binder<U, OtherAllocator>&& other,
0305 constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,
0306 constraint_t<is_constructible<T, U>::value> = 0)
0307 : allocator_(static_cast<OtherAllocator&&>(
0308 other.get_allocator())),
0309 target_(static_cast<U&&>(other.get()))
0310 {
0311 }
0312
0313
0314
0315 template <typename U, typename OtherAllocator>
0316 allocator_binder(const allocator_type& s,
0317 allocator_binder<U, OtherAllocator>&& other,
0318 constraint_t<is_constructible<T, U>::value> = 0)
0319 : allocator_(s),
0320 target_(static_cast<U&&>(other.get()))
0321 {
0322 }
0323
0324
0325 ~allocator_binder()
0326 {
0327 }
0328
0329
0330 target_type& get() noexcept
0331 {
0332 return target_;
0333 }
0334
0335
0336 const target_type& get() const noexcept
0337 {
0338 return target_;
0339 }
0340
0341
0342 allocator_type get_allocator() const noexcept
0343 {
0344 return allocator_;
0345 }
0346
0347
0348 template <typename... Args>
0349 result_of_t<T(Args...)> operator()(Args&&... args) &
0350 {
0351 return target_(static_cast<Args&&>(args)...);
0352 }
0353
0354
0355 template <typename... Args>
0356 result_of_t<T(Args...)> operator()(Args&&... args) &&
0357 {
0358 return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);
0359 }
0360
0361
0362 template <typename... Args>
0363 result_of_t<T(Args...)> operator()(Args&&... args) const&
0364 {
0365 return target_(static_cast<Args&&>(args)...);
0366 }
0367
0368 private:
0369 Allocator allocator_;
0370 T target_;
0371 };
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 template <typename Allocator>
0382 struct partial_allocator_binder
0383 {
0384
0385 explicit partial_allocator_binder(const Allocator& ex)
0386 : allocator_(ex)
0387 {
0388 }
0389
0390
0391
0392 template <typename CompletionToken>
0393 BOOST_ASIO_NODISCARD inline
0394 constexpr allocator_binder<decay_t<CompletionToken>, Allocator>
0395 operator()(CompletionToken&& completion_token) const
0396 {
0397 return allocator_binder<decay_t<CompletionToken>, Allocator>(
0398 allocator_, static_cast<CompletionToken&&>(completion_token));
0399 }
0400
0401
0402 Allocator allocator_;
0403 };
0404
0405
0406 template <typename Allocator>
0407 BOOST_ASIO_NODISCARD inline partial_allocator_binder<Allocator>
0408 bind_allocator(const Allocator& ex)
0409 {
0410 return partial_allocator_binder<Allocator>(ex);
0411 }
0412
0413
0414
0415 template <typename Allocator, typename T>
0416 BOOST_ASIO_NODISCARD inline allocator_binder<decay_t<T>, Allocator>
0417 bind_allocator(const Allocator& s, T&& t)
0418 {
0419 return allocator_binder<decay_t<T>, Allocator>(s, static_cast<T&&>(t));
0420 }
0421
0422 #if !defined(GENERATING_DOCUMENTATION)
0423
0424 namespace detail {
0425
0426 template <typename TargetAsyncResult, typename Allocator, typename = void>
0427 class allocator_binder_completion_handler_async_result
0428 {
0429 public:
0430 template <typename T>
0431 explicit allocator_binder_completion_handler_async_result(T&)
0432 {
0433 }
0434 };
0435
0436 template <typename TargetAsyncResult, typename Allocator>
0437 class allocator_binder_completion_handler_async_result<
0438 TargetAsyncResult, Allocator,
0439 void_t<typename TargetAsyncResult::completion_handler_type>>
0440 {
0441 private:
0442 TargetAsyncResult target_;
0443
0444 public:
0445 typedef allocator_binder<
0446 typename TargetAsyncResult::completion_handler_type, Allocator>
0447 completion_handler_type;
0448
0449 explicit allocator_binder_completion_handler_async_result(
0450 typename TargetAsyncResult::completion_handler_type& handler)
0451 : target_(handler)
0452 {
0453 }
0454
0455 auto get() -> decltype(target_.get())
0456 {
0457 return target_.get();
0458 }
0459 };
0460
0461 template <typename TargetAsyncResult, typename = void>
0462 struct allocator_binder_async_result_return_type
0463 {
0464 };
0465
0466 template <typename TargetAsyncResult>
0467 struct allocator_binder_async_result_return_type<
0468 TargetAsyncResult, void_type<typename TargetAsyncResult::return_type>>
0469 {
0470 typedef typename TargetAsyncResult::return_type return_type;
0471 };
0472
0473 }
0474
0475 template <typename T, typename Allocator, typename Signature>
0476 class async_result<allocator_binder<T, Allocator>, Signature> :
0477 public detail::allocator_binder_completion_handler_async_result<
0478 async_result<T, Signature>, Allocator>,
0479 public detail::allocator_binder_async_result_return_type<
0480 async_result<T, Signature>>
0481 {
0482 public:
0483 explicit async_result(allocator_binder<T, Allocator>& b)
0484 : detail::allocator_binder_completion_handler_async_result<
0485 async_result<T, Signature>, Allocator>(b.get())
0486 {
0487 }
0488
0489 template <typename Initiation>
0490 struct init_wrapper : detail::initiation_base<Initiation>
0491 {
0492 using detail::initiation_base<Initiation>::initiation_base;
0493
0494 template <typename Handler, typename... Args>
0495 void operator()(Handler&& handler, const Allocator& a, Args&&... args) &&
0496 {
0497 static_cast<Initiation&&>(*this)(
0498 allocator_binder<decay_t<Handler>, Allocator>(
0499 a, static_cast<Handler&&>(handler)),
0500 static_cast<Args&&>(args)...);
0501 }
0502
0503 template <typename Handler, typename... Args>
0504 void operator()(Handler&& handler,
0505 const Allocator& a, Args&&... args) const &
0506 {
0507 static_cast<const Initiation&>(*this)(
0508 allocator_binder<decay_t<Handler>, Allocator>(
0509 a, static_cast<Handler&&>(handler)),
0510 static_cast<Args&&>(args)...);
0511 }
0512 };
0513
0514 template <typename Initiation, typename RawCompletionToken, typename... Args>
0515 static auto initiate(Initiation&& initiation,
0516 RawCompletionToken&& token, Args&&... args)
0517 -> decltype(
0518 async_initiate<
0519 conditional_t<
0520 is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,
0521 Signature>(
0522 declval<init_wrapper<decay_t<Initiation>>>(),
0523 token.get(), token.get_allocator(), static_cast<Args&&>(args)...))
0524 {
0525 return async_initiate<
0526 conditional_t<
0527 is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,
0528 Signature>(
0529 init_wrapper<decay_t<Initiation>>(
0530 static_cast<Initiation&&>(initiation)),
0531 token.get(), token.get_allocator(), static_cast<Args&&>(args)...);
0532 }
0533
0534 private:
0535 async_result(const async_result&) = delete;
0536 async_result& operator=(const async_result&) = delete;
0537
0538 async_result<T, Signature> target_;
0539 };
0540
0541 template <typename Allocator, typename... Signatures>
0542 struct async_result<partial_allocator_binder<Allocator>, Signatures...>
0543 {
0544 template <typename Initiation, typename RawCompletionToken, typename... Args>
0545 static auto initiate(Initiation&& initiation,
0546 RawCompletionToken&& token, Args&&... args)
0547 -> decltype(
0548 async_initiate<Signatures...>(
0549 static_cast<Initiation&&>(initiation),
0550 allocator_binder<
0551 default_completion_token_t<associated_executor_t<Initiation>>,
0552 Allocator>(token.allocator_,
0553 default_completion_token_t<associated_executor_t<Initiation>>{}),
0554 static_cast<Args&&>(args)...))
0555 {
0556 return async_initiate<Signatures...>(
0557 static_cast<Initiation&&>(initiation),
0558 allocator_binder<
0559 default_completion_token_t<associated_executor_t<Initiation>>,
0560 Allocator>(token.allocator_,
0561 default_completion_token_t<associated_executor_t<Initiation>>{}),
0562 static_cast<Args&&>(args)...);
0563 }
0564 };
0565
0566 template <template <typename, typename> class Associator,
0567 typename T, typename Allocator, typename DefaultCandidate>
0568 struct associator<Associator, allocator_binder<T, Allocator>, DefaultCandidate>
0569 : Associator<T, DefaultCandidate>
0570 {
0571 static typename Associator<T, DefaultCandidate>::type get(
0572 const allocator_binder<T, Allocator>& b) noexcept
0573 {
0574 return Associator<T, DefaultCandidate>::get(b.get());
0575 }
0576
0577 static auto get(const allocator_binder<T, Allocator>& b,
0578 const DefaultCandidate& c) noexcept
0579 -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))
0580 {
0581 return Associator<T, DefaultCandidate>::get(b.get(), c);
0582 }
0583 };
0584
0585 template <typename T, typename Allocator, typename Allocator1>
0586 struct associated_allocator<allocator_binder<T, Allocator>, Allocator1>
0587 {
0588 typedef Allocator type;
0589
0590 static auto get(const allocator_binder<T, Allocator>& b,
0591 const Allocator1& = Allocator1()) noexcept
0592 -> decltype(b.get_allocator())
0593 {
0594 return b.get_allocator();
0595 }
0596 };
0597
0598 #endif
0599
0600 }
0601 }
0602
0603 #include <boost/asio/detail/pop_options.hpp>
0604
0605 #endif