any_executor.hpp 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348
  1. //
  2. // execution/any_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_EXECUTION_ANY_EXECUTOR_HPP
  11. #define BOOST_ASIO_EXECUTION_ANY_EXECUTOR_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <new>
  17. #include <typeinfo>
  18. #include <boost/asio/detail/assert.hpp>
  19. #include <boost/asio/detail/cstddef.hpp>
  20. #include <boost/asio/detail/executor_function.hpp>
  21. #include <boost/asio/detail/memory.hpp>
  22. #include <boost/asio/detail/non_const_lvalue.hpp>
  23. #include <boost/asio/detail/scoped_ptr.hpp>
  24. #include <boost/asio/detail/type_traits.hpp>
  25. #include <boost/asio/detail/throw_exception.hpp>
  26. #include <boost/asio/detail/variadic_templates.hpp>
  27. #include <boost/asio/execution/bad_executor.hpp>
  28. #include <boost/asio/execution/blocking.hpp>
  29. #include <boost/asio/execution/execute.hpp>
  30. #include <boost/asio/execution/executor.hpp>
  31. #include <boost/asio/prefer.hpp>
  32. #include <boost/asio/query.hpp>
  33. #include <boost/asio/require.hpp>
  34. #include <boost/asio/detail/push_options.hpp>
  35. namespace boost {
  36. namespace asio {
  37. #if defined(GENERATING_DOCUMENTATION)
  38. namespace execution {
  39. /// Polymorphic executor wrapper.
  40. template <typename... SupportableProperties>
  41. class any_executor
  42. {
  43. public:
  44. /// Default constructor.
  45. any_executor() noexcept;
  46. /// Construct in an empty state. Equivalent effects to default constructor.
  47. any_executor(nullptr_t) noexcept;
  48. /// Copy constructor.
  49. any_executor(const any_executor& e) noexcept;
  50. /// Move constructor.
  51. any_executor(any_executor&& e) noexcept;
  52. /// Construct to point to the same target as another any_executor.
  53. template <class... OtherSupportableProperties>
  54. any_executor(any_executor<OtherSupportableProperties...> e);
  55. /// Construct a polymorphic wrapper for the specified executor.
  56. template <typename Executor>
  57. any_executor(Executor e);
  58. /// Assignment operator.
  59. any_executor& operator=(const any_executor& e) noexcept;
  60. /// Move assignment operator.
  61. any_executor& operator=(any_executor&& e) noexcept;
  62. /// Assignment operator that sets the polymorphic wrapper to the empty state.
  63. any_executor& operator=(nullptr_t);
  64. /// Assignment operator to create a polymorphic wrapper for the specified
  65. /// executor.
  66. template <typename Executor>
  67. any_executor& operator=(Executor e);
  68. /// Destructor.
  69. ~any_executor();
  70. /// Swap targets with another polymorphic wrapper.
  71. void swap(any_executor& other) noexcept;
  72. /// Obtain a polymorphic wrapper with the specified property.
  73. /**
  74. * Do not call this function directly. It is intended for use with the
  75. * boost::asio::require and boost::asio::prefer customisation points.
  76. *
  77. * For example:
  78. * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;
  79. * auto ex2 = boost::asio::requre(ex, execution::blocking.possibly); @endcode
  80. */
  81. template <typename Property>
  82. any_executor require(Property) const;
  83. /// Obtain a polymorphic wrapper with the specified property.
  84. /**
  85. * Do not call this function directly. It is intended for use with the
  86. * boost::asio::prefer customisation point.
  87. *
  88. * For example:
  89. * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;
  90. * auto ex2 = boost::asio::prefer(ex, execution::blocking.possibly); @endcode
  91. */
  92. template <typename Property>
  93. any_executor prefer(Property) const;
  94. /// Obtain the value associated with the specified property.
  95. /**
  96. * Do not call this function directly. It is intended for use with the
  97. * boost::asio::query customisation point.
  98. *
  99. * For example:
  100. * @code execution::any_executor<execution::occupancy_t> ex = ...;
  101. * size_t n = boost::asio::query(ex, execution::occupancy); @endcode
  102. */
  103. template <typename Property>
  104. typename Property::polymorphic_query_result_type query(Property) const;
  105. /// Execute the function on the target executor.
  106. /**
  107. * Do not call this function directly. It is intended for use with the
  108. * execution::execute customisation point.
  109. *
  110. * For example:
  111. * @code execution::any_executor<> ex = ...;
  112. * execution::execute(ex, my_function_object); @endcode
  113. *
  114. * Throws boost::asio::bad_executor if the polymorphic wrapper has no target.
  115. */
  116. template <typename Function>
  117. void execute(Function&& f) const;
  118. /// Obtain the underlying execution context.
  119. /**
  120. * This function is provided for backward compatibility. It is automatically
  121. * defined when the @c SupportableProperties... list includes a property of
  122. * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>.
  123. */
  124. automatically_determined context() const;
  125. /// Determine whether the wrapper has a target executor.
  126. /**
  127. * @returns @c true if the polymorphic wrapper has a target executor,
  128. * otherwise false.
  129. */
  130. explicit operator bool() const noexcept;
  131. /// Get the type of the target executor.
  132. const type_info& target_type() const noexcept;
  133. /// Get a pointer to the target executor.
  134. template <typename Executor> Executor* target() noexcept;
  135. /// Get a pointer to the target executor.
  136. template <typename Executor> const Executor* target() const noexcept;
  137. };
  138. /// Equality operator.
  139. /**
  140. * @relates any_executor
  141. */
  142. template <typename... SupportableProperties>
  143. bool operator==(const any_executor<SupportableProperties...>& a,
  144. const any_executor<SupportableProperties...>& b) noexcept;
  145. /// Equality operator.
  146. /**
  147. * @relates any_executor
  148. */
  149. template <typename... SupportableProperties>
  150. bool operator==(const any_executor<SupportableProperties...>& a,
  151. nullptr_t) noexcept;
  152. /// Equality operator.
  153. /**
  154. * @relates any_executor
  155. */
  156. template <typename... SupportableProperties>
  157. bool operator==(nullptr_t,
  158. const any_executor<SupportableProperties...>& b) noexcept;
  159. /// Inequality operator.
  160. /**
  161. * @relates any_executor
  162. */
  163. template <typename... SupportableProperties>
  164. bool operator!=(const any_executor<SupportableProperties...>& a,
  165. const any_executor<SupportableProperties...>& b) noexcept;
  166. /// Inequality operator.
  167. /**
  168. * @relates any_executor
  169. */
  170. template <typename... SupportableProperties>
  171. bool operator!=(const any_executor<SupportableProperties...>& a,
  172. nullptr_t) noexcept;
  173. /// Inequality operator.
  174. /**
  175. * @relates any_executor
  176. */
  177. template <typename... SupportableProperties>
  178. bool operator!=(nullptr_t,
  179. const any_executor<SupportableProperties...>& b) noexcept;
  180. } // namespace execution
  181. #else // defined(GENERATING_DOCUMENTATION)
  182. namespace execution {
  183. #if !defined(BOOST_ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)
  184. #define BOOST_ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL
  185. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  186. template <typename... SupportableProperties>
  187. class any_executor;
  188. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  189. template <typename = void, typename = void, typename = void,
  190. typename = void, typename = void, typename = void,
  191. typename = void, typename = void, typename = void>
  192. class any_executor;
  193. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  194. #endif // !defined(BOOST_ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)
  195. template <typename U>
  196. struct context_as_t;
  197. namespace detail {
  198. // Traits used to detect whether a property is requirable or preferable, taking
  199. // into account that T::is_requirable or T::is_preferable may not not be well
  200. // formed.
  201. template <typename T, typename = void>
  202. struct is_requirable : false_type {};
  203. template <typename T>
  204. struct is_requirable<T, typename enable_if<T::is_requirable>::type> :
  205. true_type {};
  206. template <typename T, typename = void>
  207. struct is_preferable : false_type {};
  208. template <typename T>
  209. struct is_preferable<T, typename enable_if<T::is_preferable>::type> :
  210. true_type {};
  211. // Trait used to detect context_as property, for backward compatibility.
  212. template <typename T>
  213. struct is_context_as : false_type {};
  214. template <typename U>
  215. struct is_context_as<context_as_t<U> > : true_type {};
  216. // Helper template to:
  217. // - Check if a target can supply the supportable properties.
  218. // - Find the first convertible-from-T property in the list.
  219. template <std::size_t I, typename Props>
  220. struct supportable_properties;
  221. template <std::size_t I, typename Prop>
  222. struct supportable_properties<I, void(Prop)>
  223. {
  224. template <typename T>
  225. struct is_valid_target : integral_constant<bool,
  226. (
  227. is_requirable<Prop>::value
  228. ? can_require<T, Prop>::value
  229. : true
  230. )
  231. &&
  232. (
  233. is_preferable<Prop>::value
  234. ? can_prefer<T, Prop>::value
  235. : true
  236. )
  237. &&
  238. (
  239. !is_requirable<Prop>::value && !is_preferable<Prop>::value
  240. ? can_query<T, Prop>::value
  241. : true
  242. )
  243. >
  244. {
  245. };
  246. struct found
  247. {
  248. BOOST_ASIO_STATIC_CONSTEXPR(bool, value = true);
  249. typedef Prop type;
  250. typedef typename Prop::polymorphic_query_result_type query_result_type;
  251. BOOST_ASIO_STATIC_CONSTEXPR(std::size_t, index = I);
  252. };
  253. struct not_found
  254. {
  255. BOOST_ASIO_STATIC_CONSTEXPR(bool, value = false);
  256. };
  257. template <typename T>
  258. struct find_convertible_property :
  259. conditional<
  260. is_same<T, Prop>::value || is_convertible<T, Prop>::value,
  261. found,
  262. not_found
  263. >::type {};
  264. template <typename T>
  265. struct find_convertible_requirable_property :
  266. conditional<
  267. is_requirable<Prop>::value
  268. && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),
  269. found,
  270. not_found
  271. >::type {};
  272. template <typename T>
  273. struct find_convertible_preferable_property :
  274. conditional<
  275. is_preferable<Prop>::value
  276. && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),
  277. found,
  278. not_found
  279. >::type {};
  280. struct find_context_as_property :
  281. conditional<
  282. is_context_as<Prop>::value,
  283. found,
  284. not_found
  285. >::type {};
  286. };
  287. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  288. template <std::size_t I, typename Head, typename... Tail>
  289. struct supportable_properties<I, void(Head, Tail...)>
  290. {
  291. template <typename T>
  292. struct is_valid_target : integral_constant<bool,
  293. (
  294. supportable_properties<I,
  295. void(Head)>::template is_valid_target<T>::value
  296. &&
  297. supportable_properties<I + 1,
  298. void(Tail...)>::template is_valid_target<T>::value
  299. )
  300. >
  301. {
  302. };
  303. template <typename T>
  304. struct find_convertible_property :
  305. conditional<
  306. is_convertible<T, Head>::value,
  307. typename supportable_properties<I, void(Head)>::found,
  308. typename supportable_properties<I + 1,
  309. void(Tail...)>::template find_convertible_property<T>
  310. >::type {};
  311. template <typename T>
  312. struct find_convertible_requirable_property :
  313. conditional<
  314. is_requirable<Head>::value
  315. && is_convertible<T, Head>::value,
  316. typename supportable_properties<I, void(Head)>::found,
  317. typename supportable_properties<I + 1,
  318. void(Tail...)>::template find_convertible_requirable_property<T>
  319. >::type {};
  320. template <typename T>
  321. struct find_convertible_preferable_property :
  322. conditional<
  323. is_preferable<Head>::value
  324. && is_convertible<T, Head>::value,
  325. typename supportable_properties<I, void(Head)>::found,
  326. typename supportable_properties<I + 1,
  327. void(Tail...)>::template find_convertible_preferable_property<T>
  328. >::type {};
  329. struct find_context_as_property :
  330. conditional<
  331. is_context_as<Head>::value,
  332. typename supportable_properties<I, void(Head)>::found,
  333. typename supportable_properties<I + 1,
  334. void(Tail...)>::find_context_as_property
  335. >::type {};
  336. };
  337. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  338. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF(n) \
  339. template <std::size_t I, \
  340. typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  341. struct supportable_properties<I, \
  342. void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
  343. { \
  344. template <typename T> \
  345. struct is_valid_target : integral_constant<bool, \
  346. ( \
  347. supportable_properties<I, \
  348. void(Head)>::template is_valid_target<T>::value \
  349. && \
  350. supportable_properties<I + 1, \
  351. void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  352. is_valid_target<T>::value \
  353. ) \
  354. > \
  355. { \
  356. }; \
  357. \
  358. template <typename T> \
  359. struct find_convertible_property : \
  360. conditional< \
  361. is_convertible<T, Head>::value, \
  362. typename supportable_properties<I, void(Head)>::found, \
  363. typename supportable_properties<I + 1, \
  364. void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  365. find_convertible_property<T> \
  366. >::type {}; \
  367. \
  368. template <typename T> \
  369. struct find_convertible_requirable_property : \
  370. conditional< \
  371. is_requirable<Head>::value \
  372. && is_convertible<T, Head>::value, \
  373. typename supportable_properties<I, void(Head)>::found, \
  374. typename supportable_properties<I + 1, \
  375. void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  376. find_convertible_requirable_property<T> \
  377. >::type {}; \
  378. \
  379. template <typename T> \
  380. struct find_convertible_preferable_property : \
  381. conditional< \
  382. is_preferable<Head>::value \
  383. && is_convertible<T, Head>::value, \
  384. typename supportable_properties<I, void(Head)>::found, \
  385. typename supportable_properties<I + 1, \
  386. void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  387. find_convertible_preferable_property<T> \
  388. >::type {}; \
  389. \
  390. struct find_context_as_property : \
  391. conditional< \
  392. is_context_as<Head>::value, \
  393. typename supportable_properties<I, void(Head)>::found, \
  394. typename supportable_properties<I + 1, void( \
  395. BOOST_ASIO_VARIADIC_TARGS(n))>::find_context_as_property \
  396. >::type {}; \
  397. }; \
  398. /**/
  399. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF)
  400. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF
  401. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  402. template <typename T, typename Props>
  403. struct is_valid_target_executor :
  404. conditional<
  405. is_executor<T>::value,
  406. typename supportable_properties<0, Props>::template is_valid_target<T>,
  407. false_type
  408. >::type
  409. {
  410. };
  411. class any_executor_base
  412. {
  413. public:
  414. any_executor_base() BOOST_ASIO_NOEXCEPT
  415. : object_fns_(object_fns_table<void>()),
  416. target_(0),
  417. target_fns_(target_fns_table<void>())
  418. {
  419. }
  420. template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
  421. any_executor_base(Executor ex, false_type)
  422. : target_fns_(target_fns_table<Executor>(
  423. any_executor_base::query_blocking(ex,
  424. can_query<const Executor&, const execution::blocking_t&>())
  425. == execution::blocking.always))
  426. {
  427. any_executor_base::construct_object(ex,
  428. integral_constant<bool,
  429. sizeof(Executor) <= sizeof(object_type)
  430. && alignment_of<Executor>::value <= alignment_of<object_type>::value
  431. >());
  432. }
  433. template <BOOST_ASIO_EXECUTION_EXECUTOR Executor>
  434. any_executor_base(Executor other, true_type)
  435. : object_fns_(object_fns_table<boost::asio::detail::shared_ptr<void> >()),
  436. target_fns_(other.target_fns_)
  437. {
  438. boost::asio::detail::shared_ptr<Executor> p =
  439. boost::asio::detail::make_shared<Executor>(
  440. BOOST_ASIO_MOVE_CAST(Executor)(other));
  441. target_ = p->template target<void>();
  442. new (&object_) boost::asio::detail::shared_ptr<void>(
  443. BOOST_ASIO_MOVE_CAST(boost::asio::detail::shared_ptr<Executor>)(p));
  444. }
  445. any_executor_base(const any_executor_base& other) BOOST_ASIO_NOEXCEPT
  446. : object_fns_(other.object_fns_),
  447. target_fns_(other.target_fns_)
  448. {
  449. object_fns_->copy(*this, other);
  450. }
  451. ~any_executor_base() BOOST_ASIO_NOEXCEPT
  452. {
  453. object_fns_->destroy(*this);
  454. }
  455. any_executor_base& operator=(
  456. const any_executor_base& other) BOOST_ASIO_NOEXCEPT
  457. {
  458. if (this != &other)
  459. {
  460. object_fns_->destroy(*this);
  461. object_fns_ = other.object_fns_;
  462. target_fns_ = other.target_fns_;
  463. object_fns_->copy(*this, other);
  464. }
  465. return *this;
  466. }
  467. any_executor_base& operator=(nullptr_t) BOOST_ASIO_NOEXCEPT
  468. {
  469. object_fns_->destroy(*this);
  470. target_ = 0;
  471. object_fns_ = object_fns_table<void>();
  472. target_fns_ = target_fns_table<void>();
  473. return *this;
  474. }
  475. #if defined(BOOST_ASIO_HAS_MOVE)
  476. any_executor_base(any_executor_base&& other) BOOST_ASIO_NOEXCEPT
  477. : object_fns_(other.object_fns_),
  478. target_fns_(other.target_fns_)
  479. {
  480. other.object_fns_ = object_fns_table<void>();
  481. other.target_fns_ = target_fns_table<void>();
  482. object_fns_->move(*this, other);
  483. other.target_ = 0;
  484. }
  485. any_executor_base& operator=(
  486. any_executor_base&& other) BOOST_ASIO_NOEXCEPT
  487. {
  488. if (this != &other)
  489. {
  490. object_fns_->destroy(*this);
  491. object_fns_ = other.object_fns_;
  492. other.object_fns_ = object_fns_table<void>();
  493. target_fns_ = other.target_fns_;
  494. other.target_fns_ = target_fns_table<void>();
  495. object_fns_->move(*this, other);
  496. other.target_ = 0;
  497. }
  498. return *this;
  499. }
  500. #endif // defined(BOOST_ASIO_HAS_MOVE)
  501. void swap(any_executor_base& other) BOOST_ASIO_NOEXCEPT
  502. {
  503. if (this != &other)
  504. {
  505. any_executor_base tmp(BOOST_ASIO_MOVE_CAST(any_executor_base)(other));
  506. other = BOOST_ASIO_MOVE_CAST(any_executor_base)(*this);
  507. *this = BOOST_ASIO_MOVE_CAST(any_executor_base)(tmp);
  508. }
  509. }
  510. template <typename F>
  511. void execute(BOOST_ASIO_MOVE_ARG(F) f) const
  512. {
  513. if (target_fns_->blocking_execute != 0)
  514. {
  515. boost::asio::detail::non_const_lvalue<F> f2(f);
  516. target_fns_->blocking_execute(*this, function_view(f2.value));
  517. }
  518. else
  519. {
  520. target_fns_->execute(*this,
  521. function(BOOST_ASIO_MOVE_CAST(F)(f), std::allocator<void>()));
  522. }
  523. }
  524. template <typename Executor>
  525. Executor* target()
  526. {
  527. return static_cast<Executor*>(target_);
  528. }
  529. template <typename Executor>
  530. const Executor* target() const
  531. {
  532. return static_cast<Executor*>(target_);
  533. }
  534. #if !defined(BOOST_ASIO_NO_TYPEID)
  535. const std::type_info& target_type() const
  536. #else // !defined(BOOST_ASIO_NO_TYPEID)
  537. const void* target_type() const
  538. #endif // !defined(BOOST_ASIO_NO_TYPEID)
  539. {
  540. return target_fns_->target_type();
  541. }
  542. struct unspecified_bool_type_t {};
  543. typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
  544. static void unspecified_bool_true(unspecified_bool_type_t) {}
  545. operator unspecified_bool_type() const BOOST_ASIO_NOEXCEPT
  546. {
  547. return target_ ? &any_executor_base::unspecified_bool_true : 0;
  548. }
  549. bool operator!() const BOOST_ASIO_NOEXCEPT
  550. {
  551. return target_ == 0;
  552. }
  553. protected:
  554. bool equality_helper(const any_executor_base& other) const BOOST_ASIO_NOEXCEPT
  555. {
  556. if (target_ == other.target_)
  557. return true;
  558. if (target_ && !other.target_)
  559. return false;
  560. if (!target_ && other.target_)
  561. return false;
  562. if (target_fns_ != other.target_fns_)
  563. return false;
  564. return target_fns_->equal(*this, other);
  565. }
  566. template <typename Ex>
  567. Ex& object()
  568. {
  569. return *static_cast<Ex*>(static_cast<void*>(&object_));
  570. }
  571. template <typename Ex>
  572. const Ex& object() const
  573. {
  574. return *static_cast<const Ex*>(static_cast<const void*>(&object_));
  575. }
  576. struct object_fns
  577. {
  578. void (*destroy)(any_executor_base&);
  579. void (*copy)(any_executor_base&, const any_executor_base&);
  580. void (*move)(any_executor_base&, any_executor_base&);
  581. const void* (*target)(const any_executor_base&);
  582. };
  583. static void destroy_void(any_executor_base&)
  584. {
  585. }
  586. static void copy_void(any_executor_base& ex1, const any_executor_base&)
  587. {
  588. ex1.target_ = 0;
  589. }
  590. static void move_void(any_executor_base& ex1, any_executor_base&)
  591. {
  592. ex1.target_ = 0;
  593. }
  594. static const void* target_void(const any_executor_base&)
  595. {
  596. return 0;
  597. }
  598. template <typename Obj>
  599. static const object_fns* object_fns_table(
  600. typename enable_if<
  601. is_same<Obj, void>::value
  602. >::type* = 0)
  603. {
  604. static const object_fns fns =
  605. {
  606. &any_executor_base::destroy_void,
  607. &any_executor_base::copy_void,
  608. &any_executor_base::move_void,
  609. &any_executor_base::target_void
  610. };
  611. return &fns;
  612. }
  613. static void destroy_shared(any_executor_base& ex)
  614. {
  615. typedef boost::asio::detail::shared_ptr<void> type;
  616. ex.object<type>().~type();
  617. }
  618. static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2)
  619. {
  620. typedef boost::asio::detail::shared_ptr<void> type;
  621. new (&ex1.object_) type(ex2.object<type>());
  622. ex1.target_ = ex2.target_;
  623. }
  624. static void move_shared(any_executor_base& ex1, any_executor_base& ex2)
  625. {
  626. typedef boost::asio::detail::shared_ptr<void> type;
  627. new (&ex1.object_) type(BOOST_ASIO_MOVE_CAST(type)(ex2.object<type>()));
  628. ex1.target_ = ex2.target_;
  629. ex2.object<type>().~type();
  630. }
  631. static const void* target_shared(const any_executor_base& ex)
  632. {
  633. typedef boost::asio::detail::shared_ptr<void> type;
  634. return ex.object<type>().get();
  635. }
  636. template <typename Obj>
  637. static const object_fns* object_fns_table(
  638. typename enable_if<
  639. is_same<Obj, boost::asio::detail::shared_ptr<void> >::value
  640. >::type* = 0)
  641. {
  642. static const object_fns fns =
  643. {
  644. &any_executor_base::destroy_shared,
  645. &any_executor_base::copy_shared,
  646. &any_executor_base::move_shared,
  647. &any_executor_base::target_shared
  648. };
  649. return &fns;
  650. }
  651. template <typename Obj>
  652. static void destroy_object(any_executor_base& ex)
  653. {
  654. ex.object<Obj>().~Obj();
  655. }
  656. template <typename Obj>
  657. static void copy_object(any_executor_base& ex1, const any_executor_base& ex2)
  658. {
  659. new (&ex1.object_) Obj(ex2.object<Obj>());
  660. ex1.target_ = &ex1.object<Obj>();
  661. }
  662. template <typename Obj>
  663. static void move_object(any_executor_base& ex1, any_executor_base& ex2)
  664. {
  665. new (&ex1.object_) Obj(BOOST_ASIO_MOVE_CAST(Obj)(ex2.object<Obj>()));
  666. ex1.target_ = &ex1.object<Obj>();
  667. ex2.object<Obj>().~Obj();
  668. }
  669. template <typename Obj>
  670. static const void* target_object(const any_executor_base& ex)
  671. {
  672. return &ex.object<Obj>();
  673. }
  674. template <typename Obj>
  675. static const object_fns* object_fns_table(
  676. typename enable_if<
  677. !is_same<Obj, void>::value
  678. && !is_same<Obj, boost::asio::detail::shared_ptr<void> >::value
  679. >::type* = 0)
  680. {
  681. static const object_fns fns =
  682. {
  683. &any_executor_base::destroy_object<Obj>,
  684. &any_executor_base::copy_object<Obj>,
  685. &any_executor_base::move_object<Obj>,
  686. &any_executor_base::target_object<Obj>
  687. };
  688. return &fns;
  689. }
  690. typedef boost::asio::detail::executor_function function;
  691. typedef boost::asio::detail::executor_function_view function_view;
  692. struct target_fns
  693. {
  694. #if !defined(BOOST_ASIO_NO_TYPEID)
  695. const std::type_info& (*target_type)();
  696. #else // !defined(BOOST_ASIO_NO_TYPEID)
  697. const void* (*target_type)();
  698. #endif // !defined(BOOST_ASIO_NO_TYPEID)
  699. bool (*equal)(const any_executor_base&, const any_executor_base&);
  700. void (*execute)(const any_executor_base&, BOOST_ASIO_MOVE_ARG(function));
  701. void (*blocking_execute)(const any_executor_base&, function_view);
  702. };
  703. #if !defined(BOOST_ASIO_NO_TYPEID)
  704. static const std::type_info& target_type_void()
  705. {
  706. return typeid(void);
  707. }
  708. #else // !defined(BOOST_ASIO_NO_TYPEID)
  709. static const void* target_type_void()
  710. {
  711. return 0;
  712. }
  713. #endif // !defined(BOOST_ASIO_NO_TYPEID)
  714. static bool equal_void(const any_executor_base&, const any_executor_base&)
  715. {
  716. return true;
  717. }
  718. static void execute_void(const any_executor_base&,
  719. BOOST_ASIO_MOVE_ARG(function))
  720. {
  721. bad_executor ex;
  722. boost::asio::detail::throw_exception(ex);
  723. }
  724. static void blocking_execute_void(const any_executor_base&, function_view)
  725. {
  726. bad_executor ex;
  727. boost::asio::detail::throw_exception(ex);
  728. }
  729. template <typename Ex>
  730. static const target_fns* target_fns_table(
  731. typename enable_if<
  732. is_same<Ex, void>::value
  733. >::type* = 0)
  734. {
  735. static const target_fns fns =
  736. {
  737. &any_executor_base::target_type_void,
  738. &any_executor_base::equal_void,
  739. &any_executor_base::execute_void,
  740. &any_executor_base::blocking_execute_void
  741. };
  742. return &fns;
  743. }
  744. #if !defined(BOOST_ASIO_NO_TYPEID)
  745. template <typename Ex>
  746. static const std::type_info& target_type_ex()
  747. {
  748. return typeid(Ex);
  749. }
  750. #else // !defined(BOOST_ASIO_NO_TYPEID)
  751. template <typename Ex>
  752. static const void* target_type_ex()
  753. {
  754. static int unique_id;
  755. return &unique_id;
  756. }
  757. #endif // !defined(BOOST_ASIO_NO_TYPEID)
  758. template <typename Ex>
  759. static bool equal_ex(const any_executor_base& ex1,
  760. const any_executor_base& ex2)
  761. {
  762. return *ex1.target<Ex>() == *ex2.target<Ex>();
  763. }
  764. template <typename Ex>
  765. static void execute_ex(const any_executor_base& ex,
  766. BOOST_ASIO_MOVE_ARG(function) f)
  767. {
  768. execution::execute(*ex.target<Ex>(), BOOST_ASIO_MOVE_CAST(function)(f));
  769. }
  770. template <typename Ex>
  771. static void blocking_execute_ex(const any_executor_base& ex, function_view f)
  772. {
  773. execution::execute(*ex.target<Ex>(), f);
  774. }
  775. template <typename Ex>
  776. static const target_fns* target_fns_table(bool is_always_blocking,
  777. typename enable_if<
  778. !is_same<Ex, void>::value
  779. >::type* = 0)
  780. {
  781. static const target_fns fns_with_execute =
  782. {
  783. &any_executor_base::target_type_ex<Ex>,
  784. &any_executor_base::equal_ex<Ex>,
  785. &any_executor_base::execute_ex<Ex>,
  786. 0
  787. };
  788. static const target_fns fns_with_blocking_execute =
  789. {
  790. &any_executor_base::target_type_ex<Ex>,
  791. &any_executor_base::equal_ex<Ex>,
  792. 0,
  793. &any_executor_base::blocking_execute_ex<Ex>
  794. };
  795. return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute;
  796. }
  797. #if defined(BOOST_ASIO_MSVC)
  798. # pragma warning (push)
  799. # pragma warning (disable:4702)
  800. #endif // defined(BOOST_ASIO_MSVC)
  801. static void query_fn_void(void*, const void*, const void*)
  802. {
  803. bad_executor ex;
  804. boost::asio::detail::throw_exception(ex);
  805. }
  806. template <typename Ex, class Prop>
  807. static void query_fn_non_void(void*, const void* ex, const void* prop,
  808. typename enable_if<
  809. boost::asio::can_query<const Ex&, const Prop&>::value
  810. && is_same<typename Prop::polymorphic_query_result_type, void>::value
  811. >::type*)
  812. {
  813. boost::asio::query(*static_cast<const Ex*>(ex),
  814. *static_cast<const Prop*>(prop));
  815. }
  816. template <typename Ex, class Prop>
  817. static void query_fn_non_void(void*, const void*, const void*,
  818. typename enable_if<
  819. !boost::asio::can_query<const Ex&, const Prop&>::value
  820. && is_same<typename Prop::polymorphic_query_result_type, void>::value
  821. >::type*)
  822. {
  823. }
  824. template <typename Ex, class Prop>
  825. static void query_fn_non_void(void* result, const void* ex, const void* prop,
  826. typename enable_if<
  827. boost::asio::can_query<const Ex&, const Prop&>::value
  828. && !is_same<typename Prop::polymorphic_query_result_type, void>::value
  829. && is_reference<typename Prop::polymorphic_query_result_type>::value
  830. >::type*)
  831. {
  832. *static_cast<typename remove_reference<
  833. typename Prop::polymorphic_query_result_type>::type**>(result)
  834. = &static_cast<typename Prop::polymorphic_query_result_type>(
  835. boost::asio::query(*static_cast<const Ex*>(ex),
  836. *static_cast<const Prop*>(prop)));
  837. }
  838. template <typename Ex, class Prop>
  839. static void query_fn_non_void(void*, const void*, const void*,
  840. typename enable_if<
  841. !boost::asio::can_query<const Ex&, const Prop&>::value
  842. && !is_same<typename Prop::polymorphic_query_result_type, void>::value
  843. && is_reference<typename Prop::polymorphic_query_result_type>::value
  844. >::type*)
  845. {
  846. std::terminate(); // Combination should not be possible.
  847. }
  848. template <typename Ex, class Prop>
  849. static void query_fn_non_void(void* result, const void* ex, const void* prop,
  850. typename enable_if<
  851. boost::asio::can_query<const Ex&, const Prop&>::value
  852. && !is_same<typename Prop::polymorphic_query_result_type, void>::value
  853. && is_scalar<typename Prop::polymorphic_query_result_type>::value
  854. >::type*)
  855. {
  856. *static_cast<typename Prop::polymorphic_query_result_type*>(result)
  857. = static_cast<typename Prop::polymorphic_query_result_type>(
  858. boost::asio::query(*static_cast<const Ex*>(ex),
  859. *static_cast<const Prop*>(prop)));
  860. }
  861. template <typename Ex, class Prop>
  862. static void query_fn_non_void(void* result, const void*, const void*,
  863. typename enable_if<
  864. !boost::asio::can_query<const Ex&, const Prop&>::value
  865. && !is_same<typename Prop::polymorphic_query_result_type, void>::value
  866. && is_scalar<typename Prop::polymorphic_query_result_type>::value
  867. >::type*)
  868. {
  869. *static_cast<typename Prop::polymorphic_query_result_type*>(result)
  870. = typename Prop::polymorphic_query_result_type();
  871. }
  872. template <typename Ex, class Prop>
  873. static void query_fn_non_void(void* result, const void* ex, const void* prop,
  874. typename enable_if<
  875. boost::asio::can_query<const Ex&, const Prop&>::value
  876. && !is_same<typename Prop::polymorphic_query_result_type, void>::value
  877. && !is_reference<typename Prop::polymorphic_query_result_type>::value
  878. && !is_scalar<typename Prop::polymorphic_query_result_type>::value
  879. >::type*)
  880. {
  881. *static_cast<typename Prop::polymorphic_query_result_type**>(result)
  882. = new typename Prop::polymorphic_query_result_type(
  883. boost::asio::query(*static_cast<const Ex*>(ex),
  884. *static_cast<const Prop*>(prop)));
  885. }
  886. template <typename Ex, class Prop>
  887. static void query_fn_non_void(void* result, const void*, const void*, ...)
  888. {
  889. *static_cast<typename Prop::polymorphic_query_result_type**>(result)
  890. = new typename Prop::polymorphic_query_result_type();
  891. }
  892. template <typename Ex, class Prop>
  893. static void query_fn_impl(void* result, const void* ex, const void* prop,
  894. typename enable_if<
  895. is_same<Ex, void>::value
  896. >::type*)
  897. {
  898. query_fn_void(result, ex, prop);
  899. }
  900. template <typename Ex, class Prop>
  901. static void query_fn_impl(void* result, const void* ex, const void* prop,
  902. typename enable_if<
  903. !is_same<Ex, void>::value
  904. >::type*)
  905. {
  906. query_fn_non_void<Ex, Prop>(result, ex, prop, 0);
  907. }
  908. template <typename Ex, class Prop>
  909. static void query_fn(void* result, const void* ex, const void* prop)
  910. {
  911. query_fn_impl<Ex, Prop>(result, ex, prop, 0);
  912. }
  913. template <typename Poly, typename Ex, class Prop>
  914. static Poly require_fn_impl(const void*, const void*,
  915. typename enable_if<
  916. is_same<Ex, void>::value
  917. >::type*)
  918. {
  919. bad_executor ex;
  920. boost::asio::detail::throw_exception(ex);
  921. return Poly();
  922. }
  923. template <typename Poly, typename Ex, class Prop>
  924. static Poly require_fn_impl(const void* ex, const void* prop,
  925. typename enable_if<
  926. !is_same<Ex, void>::value && Prop::is_requirable
  927. >::type*)
  928. {
  929. return boost::asio::require(*static_cast<const Ex*>(ex),
  930. *static_cast<const Prop*>(prop));
  931. }
  932. template <typename Poly, typename Ex, class Prop>
  933. static Poly require_fn_impl(const void*, const void*, ...)
  934. {
  935. return Poly();
  936. }
  937. template <typename Poly, typename Ex, class Prop>
  938. static Poly require_fn(const void* ex, const void* prop)
  939. {
  940. return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0);
  941. }
  942. template <typename Poly, typename Ex, class Prop>
  943. static Poly prefer_fn_impl(const void*, const void*,
  944. typename enable_if<
  945. is_same<Ex, void>::value
  946. >::type*)
  947. {
  948. bad_executor ex;
  949. boost::asio::detail::throw_exception(ex);
  950. return Poly();
  951. }
  952. template <typename Poly, typename Ex, class Prop>
  953. static Poly prefer_fn_impl(const void* ex, const void* prop,
  954. typename enable_if<
  955. !is_same<Ex, void>::value && Prop::is_preferable
  956. >::type*)
  957. {
  958. return boost::asio::prefer(*static_cast<const Ex*>(ex),
  959. *static_cast<const Prop*>(prop));
  960. }
  961. template <typename Poly, typename Ex, class Prop>
  962. static Poly prefer_fn_impl(const void*, const void*, ...)
  963. {
  964. return Poly();
  965. }
  966. template <typename Poly, typename Ex, class Prop>
  967. static Poly prefer_fn(const void* ex, const void* prop)
  968. {
  969. return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0);
  970. }
  971. template <typename Poly>
  972. struct prop_fns
  973. {
  974. void (*query)(void*, const void*, const void*);
  975. Poly (*require)(const void*, const void*);
  976. Poly (*prefer)(const void*, const void*);
  977. };
  978. #if defined(BOOST_ASIO_MSVC)
  979. # pragma warning (pop)
  980. #endif // defined(BOOST_ASIO_MSVC)
  981. private:
  982. template <typename Executor>
  983. static execution::blocking_t query_blocking(const Executor& ex, true_type)
  984. {
  985. return boost::asio::query(ex, execution::blocking);
  986. }
  987. template <typename Executor>
  988. static execution::blocking_t query_blocking(const Executor&, false_type)
  989. {
  990. return execution::blocking_t();
  991. }
  992. template <typename Executor>
  993. void construct_object(Executor& ex, true_type)
  994. {
  995. object_fns_ = object_fns_table<Executor>();
  996. target_ = new (&object_) Executor(BOOST_ASIO_MOVE_CAST(Executor)(ex));
  997. }
  998. template <typename Executor>
  999. void construct_object(Executor& ex, false_type)
  1000. {
  1001. object_fns_ = object_fns_table<boost::asio::detail::shared_ptr<void> >();
  1002. boost::asio::detail::shared_ptr<Executor> p =
  1003. boost::asio::detail::make_shared<Executor>(
  1004. BOOST_ASIO_MOVE_CAST(Executor)(ex));
  1005. target_ = p.get();
  1006. new (&object_) boost::asio::detail::shared_ptr<void>(
  1007. BOOST_ASIO_MOVE_CAST(boost::asio::detail::shared_ptr<Executor>)(p));
  1008. }
  1009. /*private:*/public:
  1010. // template <typename...> friend class any_executor;
  1011. typedef aligned_storage<
  1012. sizeof(boost::asio::detail::shared_ptr<void>),
  1013. alignment_of<boost::asio::detail::shared_ptr<void> >::value
  1014. >::type object_type;
  1015. object_type object_;
  1016. const object_fns* object_fns_;
  1017. void* target_;
  1018. const target_fns* target_fns_;
  1019. };
  1020. template <typename Derived, typename Property, typename = void>
  1021. struct any_executor_context
  1022. {
  1023. };
  1024. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  1025. template <typename Derived, typename Property>
  1026. struct any_executor_context<Derived, Property,
  1027. typename enable_if<Property::value>::type>
  1028. {
  1029. typename Property::query_result_type context() const
  1030. {
  1031. return static_cast<const Derived*>(this)->query(typename Property::type());
  1032. }
  1033. };
  1034. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  1035. } // namespace detail
  1036. template <>
  1037. class any_executor<> : public detail::any_executor_base
  1038. {
  1039. public:
  1040. any_executor() BOOST_ASIO_NOEXCEPT
  1041. : detail::any_executor_base()
  1042. {
  1043. }
  1044. any_executor(nullptr_t) BOOST_ASIO_NOEXCEPT
  1045. : detail::any_executor_base()
  1046. {
  1047. }
  1048. template <typename Executor>
  1049. any_executor(Executor ex,
  1050. typename enable_if<
  1051. conditional<
  1052. !is_same<Executor, any_executor>::value
  1053. && !is_base_of<detail::any_executor_base, Executor>::value,
  1054. is_executor<Executor>,
  1055. false_type
  1056. >::type::value
  1057. >::type* = 0)
  1058. : detail::any_executor_base(
  1059. BOOST_ASIO_MOVE_CAST(Executor)(ex), false_type())
  1060. {
  1061. }
  1062. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1063. template <typename... OtherSupportableProperties>
  1064. any_executor(any_executor<OtherSupportableProperties...> other)
  1065. : detail::any_executor_base(
  1066. static_cast<const detail::any_executor_base&>(other))
  1067. {
  1068. }
  1069. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1070. template <typename U0, typename U1, typename U2, typename U3,
  1071. typename U4, typename U5, typename U6, typename U7>
  1072. any_executor(any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other)
  1073. : detail::any_executor_base(
  1074. static_cast<const detail::any_executor_base&>(other))
  1075. {
  1076. }
  1077. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1078. any_executor(const any_executor& other) BOOST_ASIO_NOEXCEPT
  1079. : detail::any_executor_base(
  1080. static_cast<const detail::any_executor_base&>(other))
  1081. {
  1082. }
  1083. any_executor& operator=(const any_executor& other) BOOST_ASIO_NOEXCEPT
  1084. {
  1085. if (this != &other)
  1086. {
  1087. detail::any_executor_base::operator=(
  1088. static_cast<const detail::any_executor_base&>(other));
  1089. }
  1090. return *this;
  1091. }
  1092. any_executor& operator=(nullptr_t p) BOOST_ASIO_NOEXCEPT
  1093. {
  1094. detail::any_executor_base::operator=(p);
  1095. return *this;
  1096. }
  1097. #if defined(BOOST_ASIO_HAS_MOVE)
  1098. any_executor(any_executor&& other) BOOST_ASIO_NOEXCEPT
  1099. : detail::any_executor_base(
  1100. static_cast<any_executor_base&&>(
  1101. static_cast<any_executor_base&>(other)))
  1102. {
  1103. }
  1104. any_executor& operator=(any_executor&& other) BOOST_ASIO_NOEXCEPT
  1105. {
  1106. if (this != &other)
  1107. {
  1108. detail::any_executor_base::operator=(
  1109. static_cast<detail::any_executor_base&&>(
  1110. static_cast<detail::any_executor_base&>(other)));
  1111. }
  1112. return *this;
  1113. }
  1114. #endif // defined(BOOST_ASIO_HAS_MOVE)
  1115. void swap(any_executor& other) BOOST_ASIO_NOEXCEPT
  1116. {
  1117. detail::any_executor_base::swap(
  1118. static_cast<detail::any_executor_base&>(other));
  1119. }
  1120. using detail::any_executor_base::execute;
  1121. using detail::any_executor_base::target;
  1122. using detail::any_executor_base::target_type;
  1123. using detail::any_executor_base::operator unspecified_bool_type;
  1124. using detail::any_executor_base::operator!;
  1125. bool equality_helper(const any_executor& other) const BOOST_ASIO_NOEXCEPT
  1126. {
  1127. return any_executor_base::equality_helper(other);
  1128. }
  1129. template <typename AnyExecutor1, typename AnyExecutor2>
  1130. friend typename enable_if<
  1131. is_same<AnyExecutor1, any_executor>::value
  1132. || is_same<AnyExecutor2, any_executor>::value,
  1133. bool
  1134. >::type operator==(const AnyExecutor1& a,
  1135. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT
  1136. {
  1137. return static_cast<const any_executor&>(a).equality_helper(b);
  1138. }
  1139. template <typename AnyExecutor>
  1140. friend typename enable_if<
  1141. is_same<AnyExecutor, any_executor>::value,
  1142. bool
  1143. >::type operator==(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT
  1144. {
  1145. return !a;
  1146. }
  1147. template <typename AnyExecutor>
  1148. friend typename enable_if<
  1149. is_same<AnyExecutor, any_executor>::value,
  1150. bool
  1151. >::type operator==(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT
  1152. {
  1153. return !b;
  1154. }
  1155. template <typename AnyExecutor1, typename AnyExecutor2>
  1156. friend typename enable_if<
  1157. is_same<AnyExecutor1, any_executor>::value
  1158. || is_same<AnyExecutor2, any_executor>::value,
  1159. bool
  1160. >::type operator!=(const AnyExecutor1& a,
  1161. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT
  1162. {
  1163. return !static_cast<const any_executor&>(a).equality_helper(b);
  1164. }
  1165. template <typename AnyExecutor>
  1166. friend typename enable_if<
  1167. is_same<AnyExecutor, any_executor>::value,
  1168. bool
  1169. >::type operator!=(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT
  1170. {
  1171. return !!a;
  1172. }
  1173. template <typename AnyExecutor>
  1174. friend typename enable_if<
  1175. is_same<AnyExecutor, any_executor>::value,
  1176. bool
  1177. >::type operator!=(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT
  1178. {
  1179. return !!b;
  1180. }
  1181. };
  1182. inline void swap(any_executor<>& a, any_executor<>& b) BOOST_ASIO_NOEXCEPT
  1183. {
  1184. return a.swap(b);
  1185. }
  1186. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1187. template <typename... SupportableProperties>
  1188. class any_executor :
  1189. public detail::any_executor_base,
  1190. public detail::any_executor_context<
  1191. any_executor<SupportableProperties...>,
  1192. typename detail::supportable_properties<
  1193. 0, void(SupportableProperties...)>::find_context_as_property>
  1194. {
  1195. public:
  1196. any_executor() BOOST_ASIO_NOEXCEPT
  1197. : detail::any_executor_base(),
  1198. prop_fns_(prop_fns_table<void>())
  1199. {
  1200. }
  1201. any_executor(nullptr_t) BOOST_ASIO_NOEXCEPT
  1202. : detail::any_executor_base(),
  1203. prop_fns_(prop_fns_table<void>())
  1204. {
  1205. }
  1206. template <typename Executor>
  1207. any_executor(Executor ex,
  1208. typename enable_if<
  1209. conditional<
  1210. !is_same<Executor, any_executor>::value
  1211. && !is_base_of<detail::any_executor_base, Executor>::value,
  1212. detail::is_valid_target_executor<
  1213. Executor, void(SupportableProperties...)>,
  1214. false_type
  1215. >::type::value
  1216. >::type* = 0)
  1217. : detail::any_executor_base(
  1218. BOOST_ASIO_MOVE_CAST(Executor)(ex), false_type()),
  1219. prop_fns_(prop_fns_table<Executor>())
  1220. {
  1221. }
  1222. template <typename... OtherSupportableProperties>
  1223. any_executor(any_executor<OtherSupportableProperties...> other,
  1224. typename enable_if<
  1225. conditional<
  1226. !is_same<
  1227. any_executor<OtherSupportableProperties...>,
  1228. any_executor
  1229. >::value,
  1230. typename detail::supportable_properties<
  1231. 0, void(SupportableProperties...)>::template is_valid_target<
  1232. any_executor<OtherSupportableProperties...> >,
  1233. false_type
  1234. >::type::value
  1235. >::type* = 0)
  1236. : detail::any_executor_base(BOOST_ASIO_MOVE_CAST(
  1237. any_executor<OtherSupportableProperties...>)(other), true_type()),
  1238. prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >())
  1239. {
  1240. }
  1241. any_executor(const any_executor& other) BOOST_ASIO_NOEXCEPT
  1242. : detail::any_executor_base(
  1243. static_cast<const detail::any_executor_base&>(other)),
  1244. prop_fns_(other.prop_fns_)
  1245. {
  1246. }
  1247. any_executor& operator=(const any_executor& other) BOOST_ASIO_NOEXCEPT
  1248. {
  1249. if (this != &other)
  1250. {
  1251. prop_fns_ = other.prop_fns_;
  1252. detail::any_executor_base::operator=(
  1253. static_cast<const detail::any_executor_base&>(other));
  1254. }
  1255. return *this;
  1256. }
  1257. any_executor& operator=(nullptr_t p) BOOST_ASIO_NOEXCEPT
  1258. {
  1259. prop_fns_ = prop_fns_table<void>();
  1260. detail::any_executor_base::operator=(p);
  1261. return *this;
  1262. }
  1263. #if defined(BOOST_ASIO_HAS_MOVE)
  1264. any_executor(any_executor&& other) BOOST_ASIO_NOEXCEPT
  1265. : detail::any_executor_base(
  1266. static_cast<any_executor_base&&>(
  1267. static_cast<any_executor_base&>(other))),
  1268. prop_fns_(other.prop_fns_)
  1269. {
  1270. other.prop_fns_ = prop_fns_table<void>();
  1271. }
  1272. any_executor& operator=(any_executor&& other) BOOST_ASIO_NOEXCEPT
  1273. {
  1274. if (this != &other)
  1275. {
  1276. prop_fns_ = other.prop_fns_;
  1277. detail::any_executor_base::operator=(
  1278. static_cast<detail::any_executor_base&&>(
  1279. static_cast<detail::any_executor_base&>(other)));
  1280. }
  1281. return *this;
  1282. }
  1283. #endif // defined(BOOST_ASIO_HAS_MOVE)
  1284. void swap(any_executor& other) BOOST_ASIO_NOEXCEPT
  1285. {
  1286. if (this != &other)
  1287. {
  1288. detail::any_executor_base::swap(
  1289. static_cast<detail::any_executor_base&>(other));
  1290. const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_;
  1291. other.prop_fns_ = prop_fns_;
  1292. prop_fns_ = tmp_prop_fns;
  1293. }
  1294. }
  1295. using detail::any_executor_base::execute;
  1296. using detail::any_executor_base::target;
  1297. using detail::any_executor_base::target_type;
  1298. using detail::any_executor_base::operator unspecified_bool_type;
  1299. using detail::any_executor_base::operator!;
  1300. bool equality_helper(const any_executor& other) const BOOST_ASIO_NOEXCEPT
  1301. {
  1302. return any_executor_base::equality_helper(other);
  1303. }
  1304. template <typename AnyExecutor1, typename AnyExecutor2>
  1305. friend typename enable_if<
  1306. is_same<AnyExecutor1, any_executor>::value
  1307. || is_same<AnyExecutor2, any_executor>::value,
  1308. bool
  1309. >::type operator==(const AnyExecutor1& a,
  1310. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT
  1311. {
  1312. return static_cast<const any_executor&>(a).equality_helper(b);
  1313. }
  1314. template <typename AnyExecutor>
  1315. friend typename enable_if<
  1316. is_same<AnyExecutor, any_executor>::value,
  1317. bool
  1318. >::type operator==(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT
  1319. {
  1320. return !a;
  1321. }
  1322. template <typename AnyExecutor>
  1323. friend typename enable_if<
  1324. is_same<AnyExecutor, any_executor>::value,
  1325. bool
  1326. >::type operator==(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT
  1327. {
  1328. return !b;
  1329. }
  1330. template <typename AnyExecutor1, typename AnyExecutor2>
  1331. friend typename enable_if<
  1332. is_same<AnyExecutor1, any_executor>::value
  1333. || is_same<AnyExecutor2, any_executor>::value,
  1334. bool
  1335. >::type operator!=(const AnyExecutor1& a,
  1336. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT
  1337. {
  1338. return !static_cast<const any_executor&>(a).equality_helper(b);
  1339. }
  1340. template <typename AnyExecutor>
  1341. friend typename enable_if<
  1342. is_same<AnyExecutor, any_executor>::value,
  1343. bool
  1344. >::type operator!=(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT
  1345. {
  1346. return !!a;
  1347. }
  1348. template <typename AnyExecutor>
  1349. friend typename enable_if<
  1350. is_same<AnyExecutor, any_executor>::value,
  1351. bool
  1352. >::type operator!=(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT
  1353. {
  1354. return !!b;
  1355. }
  1356. template <typename T>
  1357. struct find_convertible_property :
  1358. detail::supportable_properties<
  1359. 0, void(SupportableProperties...)>::template
  1360. find_convertible_property<T> {};
  1361. template <typename Property>
  1362. void query(const Property& p,
  1363. typename enable_if<
  1364. is_same<
  1365. typename find_convertible_property<Property>::query_result_type,
  1366. void
  1367. >::value
  1368. >::type* = 0) const
  1369. {
  1370. typedef find_convertible_property<Property> found;
  1371. prop_fns_[found::index].query(0, object_fns_->target(*this),
  1372. &static_cast<const typename found::type&>(p));
  1373. }
  1374. template <typename Property>
  1375. typename find_convertible_property<Property>::query_result_type
  1376. query(const Property& p,
  1377. typename enable_if<
  1378. !is_same<
  1379. typename find_convertible_property<Property>::query_result_type,
  1380. void
  1381. >::value
  1382. &&
  1383. is_reference<
  1384. typename find_convertible_property<Property>::query_result_type
  1385. >::value
  1386. >::type* = 0) const
  1387. {
  1388. typedef find_convertible_property<Property> found;
  1389. typename remove_reference<
  1390. typename found::query_result_type>::type* result = 0;
  1391. prop_fns_[found::index].query(&result, object_fns_->target(*this),
  1392. &static_cast<const typename found::type&>(p));
  1393. return *result;
  1394. }
  1395. template <typename Property>
  1396. typename find_convertible_property<Property>::query_result_type
  1397. query(const Property& p,
  1398. typename enable_if<
  1399. !is_same<
  1400. typename find_convertible_property<Property>::query_result_type,
  1401. void
  1402. >::value
  1403. &&
  1404. is_scalar<
  1405. typename find_convertible_property<Property>::query_result_type
  1406. >::value
  1407. >::type* = 0) const
  1408. {
  1409. typedef find_convertible_property<Property> found;
  1410. typename found::query_result_type result;
  1411. prop_fns_[found::index].query(&result, object_fns_->target(*this),
  1412. &static_cast<const typename found::type&>(p));
  1413. return result;
  1414. }
  1415. template <typename Property>
  1416. typename find_convertible_property<Property>::query_result_type
  1417. query(const Property& p,
  1418. typename enable_if<
  1419. !is_same<
  1420. typename find_convertible_property<Property>::query_result_type,
  1421. void
  1422. >::value
  1423. &&
  1424. !is_reference<
  1425. typename find_convertible_property<Property>::query_result_type
  1426. >::value
  1427. &&
  1428. !is_scalar<
  1429. typename find_convertible_property<Property>::query_result_type
  1430. >::value
  1431. >::type* = 0) const
  1432. {
  1433. typedef find_convertible_property<Property> found;
  1434. typename found::query_result_type* result;
  1435. prop_fns_[found::index].query(&result, object_fns_->target(*this),
  1436. &static_cast<const typename found::type&>(p));
  1437. return *boost::asio::detail::scoped_ptr<
  1438. typename found::query_result_type>(result);
  1439. }
  1440. template <typename T>
  1441. struct find_convertible_requirable_property :
  1442. detail::supportable_properties<
  1443. 0, void(SupportableProperties...)>::template
  1444. find_convertible_requirable_property<T> {};
  1445. template <typename Property>
  1446. any_executor require(const Property& p,
  1447. typename enable_if<
  1448. find_convertible_requirable_property<Property>::value
  1449. >::type* = 0) const
  1450. {
  1451. typedef find_convertible_requirable_property<Property> found;
  1452. return prop_fns_[found::index].require(object_fns_->target(*this),
  1453. &static_cast<const typename found::type&>(p));
  1454. }
  1455. template <typename T>
  1456. struct find_convertible_preferable_property :
  1457. detail::supportable_properties<
  1458. 0, void(SupportableProperties...)>::template
  1459. find_convertible_preferable_property<T> {};
  1460. template <typename Property>
  1461. any_executor prefer(const Property& p,
  1462. typename enable_if<
  1463. find_convertible_preferable_property<Property>::value
  1464. >::type* = 0) const
  1465. {
  1466. typedef find_convertible_preferable_property<Property> found;
  1467. return prop_fns_[found::index].prefer(object_fns_->target(*this),
  1468. &static_cast<const typename found::type&>(p));
  1469. }
  1470. //private:
  1471. template <typename Ex>
  1472. static const prop_fns<any_executor>* prop_fns_table()
  1473. {
  1474. static const prop_fns<any_executor> fns[] =
  1475. {
  1476. {
  1477. &detail::any_executor_base::query_fn<
  1478. Ex, SupportableProperties>,
  1479. &detail::any_executor_base::require_fn<
  1480. any_executor, Ex, SupportableProperties>,
  1481. &detail::any_executor_base::prefer_fn<
  1482. any_executor, Ex, SupportableProperties>
  1483. }...
  1484. };
  1485. return fns;
  1486. }
  1487. const prop_fns<any_executor>* prop_fns_;
  1488. };
  1489. template <typename... SupportableProperties>
  1490. inline void swap(any_executor<SupportableProperties...>& a,
  1491. any_executor<SupportableProperties...>& b) BOOST_ASIO_NOEXCEPT
  1492. {
  1493. return a.swap(b);
  1494. }
  1495. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1496. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \
  1497. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_##n
  1498. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1 \
  1499. { \
  1500. &detail::any_executor_base::query_fn<Ex, T1>, \
  1501. &detail::any_executor_base::require_fn<any_executor, Ex, T1>, \
  1502. &detail::any_executor_base::prefer_fn<any_executor, Ex, T1> \
  1503. }
  1504. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2 \
  1505. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1, \
  1506. { \
  1507. &detail::any_executor_base::query_fn<Ex, T2>, \
  1508. &detail::any_executor_base::require_fn<any_executor, Ex, T2>, \
  1509. &detail::any_executor_base::prefer_fn<any_executor, Ex, T2> \
  1510. }
  1511. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3 \
  1512. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2, \
  1513. { \
  1514. &detail::any_executor_base::query_fn<Ex, T3>, \
  1515. &detail::any_executor_base::require_fn<any_executor, Ex, T3>, \
  1516. &detail::any_executor_base::prefer_fn<any_executor, Ex, T3> \
  1517. }
  1518. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4 \
  1519. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3, \
  1520. { \
  1521. &detail::any_executor_base::query_fn<Ex, T4>, \
  1522. &detail::any_executor_base::require_fn<any_executor, Ex, T4>, \
  1523. &detail::any_executor_base::prefer_fn<any_executor, Ex, T4> \
  1524. }
  1525. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5 \
  1526. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4, \
  1527. { \
  1528. &detail::any_executor_base::query_fn<Ex, T5>, \
  1529. &detail::any_executor_base::require_fn<any_executor, Ex, T5>, \
  1530. &detail::any_executor_base::prefer_fn<any_executor, Ex, T5> \
  1531. }
  1532. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6 \
  1533. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5, \
  1534. { \
  1535. &detail::any_executor_base::query_fn<Ex, T6>, \
  1536. &detail::any_executor_base::require_fn<any_executor, Ex, T6>, \
  1537. &detail::any_executor_base::prefer_fn<any_executor, Ex, T6> \
  1538. }
  1539. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7 \
  1540. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6, \
  1541. { \
  1542. &detail::any_executor_base::query_fn<Ex, T7>, \
  1543. &detail::any_executor_base::require_fn<any_executor, Ex, T7>, \
  1544. &detail::any_executor_base::prefer_fn<any_executor, Ex, T7> \
  1545. }
  1546. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8 \
  1547. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7, \
  1548. { \
  1549. &detail::any_executor_base::query_fn<Ex, T8>, \
  1550. &detail::any_executor_base::require_fn<any_executor, Ex, T8>, \
  1551. &detail::any_executor_base::prefer_fn<any_executor, Ex, T8> \
  1552. }
  1553. #if defined(BOOST_ASIO_HAS_MOVE)
  1554. # define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \
  1555. any_executor(any_executor&& other) BOOST_ASIO_NOEXCEPT \
  1556. : detail::any_executor_base( \
  1557. static_cast<any_executor_base&&>( \
  1558. static_cast<any_executor_base&>(other))), \
  1559. prop_fns_(other.prop_fns_) \
  1560. { \
  1561. other.prop_fns_ = prop_fns_table<void>(); \
  1562. } \
  1563. \
  1564. any_executor& operator=(any_executor&& other) BOOST_ASIO_NOEXCEPT \
  1565. { \
  1566. if (this != &other) \
  1567. { \
  1568. prop_fns_ = other.prop_fns_; \
  1569. detail::any_executor_base::operator=( \
  1570. static_cast<detail::any_executor_base&&>( \
  1571. static_cast<detail::any_executor_base&>(other))); \
  1572. } \
  1573. return *this; \
  1574. } \
  1575. /**/
  1576. #else // defined(BOOST_ASIO_HAS_MOVE)
  1577. # define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS
  1578. #endif // defined(BOOST_ASIO_HAS_MOVE)
  1579. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_DEF(n) \
  1580. template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  1581. class any_executor<BOOST_ASIO_VARIADIC_TARGS(n)> : \
  1582. public detail::any_executor_base, \
  1583. public detail::any_executor_context< \
  1584. any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>, \
  1585. typename detail::supportable_properties< \
  1586. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::find_context_as_property> \
  1587. { \
  1588. public: \
  1589. any_executor() BOOST_ASIO_NOEXCEPT \
  1590. : detail::any_executor_base(), \
  1591. prop_fns_(prop_fns_table<void>()) \
  1592. { \
  1593. } \
  1594. \
  1595. any_executor(nullptr_t) BOOST_ASIO_NOEXCEPT \
  1596. : detail::any_executor_base(), \
  1597. prop_fns_(prop_fns_table<void>()) \
  1598. { \
  1599. } \
  1600. \
  1601. template <BOOST_ASIO_EXECUTION_EXECUTOR Executor> \
  1602. any_executor(Executor ex, \
  1603. typename enable_if< \
  1604. conditional< \
  1605. !is_same<Executor, any_executor>::value \
  1606. && !is_base_of<detail::any_executor_base, Executor>::value, \
  1607. detail::is_valid_target_executor< \
  1608. Executor, void(BOOST_ASIO_VARIADIC_TARGS(n))>, \
  1609. false_type \
  1610. >::type::value \
  1611. >::type* = 0) \
  1612. : detail::any_executor_base(BOOST_ASIO_MOVE_CAST( \
  1613. Executor)(ex), false_type()), \
  1614. prop_fns_(prop_fns_table<Executor>()) \
  1615. { \
  1616. } \
  1617. \
  1618. any_executor(const any_executor& other) BOOST_ASIO_NOEXCEPT \
  1619. : detail::any_executor_base( \
  1620. static_cast<const detail::any_executor_base&>(other)), \
  1621. prop_fns_(other.prop_fns_) \
  1622. { \
  1623. } \
  1624. \
  1625. any_executor(any_executor<> other) \
  1626. : detail::any_executor_base(BOOST_ASIO_MOVE_CAST( \
  1627. any_executor<>)(other), true_type()), \
  1628. prop_fns_(prop_fns_table<any_executor<> >()) \
  1629. { \
  1630. } \
  1631. \
  1632. template <typename OtherAnyExecutor> \
  1633. any_executor(OtherAnyExecutor other, \
  1634. typename enable_if< \
  1635. conditional< \
  1636. !is_same<OtherAnyExecutor, any_executor>::value \
  1637. && is_base_of<detail::any_executor_base, \
  1638. OtherAnyExecutor>::value, \
  1639. typename detail::supportable_properties< \
  1640. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  1641. is_valid_target<OtherAnyExecutor>, \
  1642. false_type \
  1643. >::type::value \
  1644. >::type* = 0) \
  1645. : detail::any_executor_base(BOOST_ASIO_MOVE_CAST( \
  1646. OtherAnyExecutor)(other), true_type()), \
  1647. prop_fns_(prop_fns_table<OtherAnyExecutor>()) \
  1648. { \
  1649. } \
  1650. \
  1651. any_executor& operator=(const any_executor& other) BOOST_ASIO_NOEXCEPT \
  1652. { \
  1653. if (this != &other) \
  1654. { \
  1655. prop_fns_ = other.prop_fns_; \
  1656. detail::any_executor_base::operator=( \
  1657. static_cast<const detail::any_executor_base&>(other)); \
  1658. } \
  1659. return *this; \
  1660. } \
  1661. \
  1662. any_executor& operator=(nullptr_t p) BOOST_ASIO_NOEXCEPT \
  1663. { \
  1664. prop_fns_ = prop_fns_table<void>(); \
  1665. detail::any_executor_base::operator=(p); \
  1666. return *this; \
  1667. } \
  1668. \
  1669. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \
  1670. \
  1671. void swap(any_executor& other) BOOST_ASIO_NOEXCEPT \
  1672. { \
  1673. if (this != &other) \
  1674. { \
  1675. detail::any_executor_base::swap( \
  1676. static_cast<detail::any_executor_base&>(other)); \
  1677. const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_; \
  1678. other.prop_fns_ = prop_fns_; \
  1679. prop_fns_ = tmp_prop_fns; \
  1680. } \
  1681. } \
  1682. \
  1683. using detail::any_executor_base::execute; \
  1684. using detail::any_executor_base::target; \
  1685. using detail::any_executor_base::target_type; \
  1686. using detail::any_executor_base::operator unspecified_bool_type; \
  1687. using detail::any_executor_base::operator!; \
  1688. \
  1689. bool equality_helper(const any_executor& other) const BOOST_ASIO_NOEXCEPT \
  1690. { \
  1691. return any_executor_base::equality_helper(other); \
  1692. } \
  1693. \
  1694. template <typename AnyExecutor1, typename AnyExecutor2> \
  1695. friend typename enable_if< \
  1696. is_same<AnyExecutor1, any_executor>::value \
  1697. || is_same<AnyExecutor2, any_executor>::value, \
  1698. bool \
  1699. >::type operator==(const AnyExecutor1& a, \
  1700. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT \
  1701. { \
  1702. return static_cast<const any_executor&>(a).equality_helper(b); \
  1703. } \
  1704. \
  1705. template <typename AnyExecutor> \
  1706. friend typename enable_if< \
  1707. is_same<AnyExecutor, any_executor>::value, \
  1708. bool \
  1709. >::type operator==(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT \
  1710. { \
  1711. return !a; \
  1712. } \
  1713. \
  1714. template <typename AnyExecutor> \
  1715. friend typename enable_if< \
  1716. is_same<AnyExecutor, any_executor>::value, \
  1717. bool \
  1718. >::type operator==(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT \
  1719. { \
  1720. return !b; \
  1721. } \
  1722. \
  1723. template <typename AnyExecutor1, typename AnyExecutor2> \
  1724. friend typename enable_if< \
  1725. is_same<AnyExecutor1, any_executor>::value \
  1726. || is_same<AnyExecutor2, any_executor>::value, \
  1727. bool \
  1728. >::type operator!=(const AnyExecutor1& a, \
  1729. const AnyExecutor2& b) BOOST_ASIO_NOEXCEPT \
  1730. { \
  1731. return !static_cast<const any_executor&>(a).equality_helper(b); \
  1732. } \
  1733. \
  1734. template <typename AnyExecutor> \
  1735. friend typename enable_if< \
  1736. is_same<AnyExecutor, any_executor>::value, \
  1737. bool \
  1738. >::type operator!=(const AnyExecutor& a, nullptr_t) BOOST_ASIO_NOEXCEPT \
  1739. { \
  1740. return !!a; \
  1741. } \
  1742. \
  1743. template <typename AnyExecutor> \
  1744. friend typename enable_if< \
  1745. is_same<AnyExecutor, any_executor>::value, \
  1746. bool \
  1747. >::type operator!=(nullptr_t, const AnyExecutor& b) BOOST_ASIO_NOEXCEPT \
  1748. { \
  1749. return !!b; \
  1750. } \
  1751. \
  1752. template <typename T> \
  1753. struct find_convertible_property : \
  1754. detail::supportable_properties< \
  1755. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  1756. find_convertible_property<T> {}; \
  1757. \
  1758. template <typename Property> \
  1759. void query(const Property& p, \
  1760. typename enable_if< \
  1761. is_same< \
  1762. typename find_convertible_property<Property>::query_result_type, \
  1763. void \
  1764. >::value \
  1765. >::type* = 0) const \
  1766. { \
  1767. typedef find_convertible_property<Property> found; \
  1768. prop_fns_[found::index].query(0, object_fns_->target(*this), \
  1769. &static_cast<const typename found::type&>(p)); \
  1770. } \
  1771. \
  1772. template <typename Property> \
  1773. typename find_convertible_property<Property>::query_result_type \
  1774. query(const Property& p, \
  1775. typename enable_if< \
  1776. !is_same< \
  1777. typename find_convertible_property<Property>::query_result_type, \
  1778. void \
  1779. >::value \
  1780. && \
  1781. is_reference< \
  1782. typename find_convertible_property<Property>::query_result_type \
  1783. >::value \
  1784. >::type* = 0) const \
  1785. { \
  1786. typedef find_convertible_property<Property> found; \
  1787. typename remove_reference< \
  1788. typename found::query_result_type>::type* result; \
  1789. prop_fns_[found::index].query(&result, object_fns_->target(*this), \
  1790. &static_cast<const typename found::type&>(p)); \
  1791. return *result; \
  1792. } \
  1793. \
  1794. template <typename Property> \
  1795. typename find_convertible_property<Property>::query_result_type \
  1796. query(const Property& p, \
  1797. typename enable_if< \
  1798. !is_same< \
  1799. typename find_convertible_property<Property>::query_result_type, \
  1800. void \
  1801. >::value \
  1802. && \
  1803. is_scalar< \
  1804. typename find_convertible_property<Property>::query_result_type \
  1805. >::value \
  1806. >::type* = 0) const \
  1807. { \
  1808. typedef find_convertible_property<Property> found; \
  1809. typename found::query_result_type result; \
  1810. prop_fns_[found::index].query(&result, object_fns_->target(*this), \
  1811. &static_cast<const typename found::type&>(p)); \
  1812. return result; \
  1813. } \
  1814. \
  1815. template <typename Property> \
  1816. typename find_convertible_property<Property>::query_result_type \
  1817. query(const Property& p, \
  1818. typename enable_if< \
  1819. !is_same< \
  1820. typename find_convertible_property<Property>::query_result_type, \
  1821. void \
  1822. >::value \
  1823. && \
  1824. !is_reference< \
  1825. typename find_convertible_property<Property>::query_result_type \
  1826. >::value \
  1827. && \
  1828. !is_scalar< \
  1829. typename find_convertible_property<Property>::query_result_type \
  1830. >::value \
  1831. >::type* = 0) const \
  1832. { \
  1833. typedef find_convertible_property<Property> found; \
  1834. typename found::query_result_type* result; \
  1835. prop_fns_[found::index].query(&result, object_fns_->target(*this), \
  1836. &static_cast<const typename found::type&>(p)); \
  1837. return *boost::asio::detail::scoped_ptr< \
  1838. typename found::query_result_type>(result); \
  1839. } \
  1840. \
  1841. template <typename T> \
  1842. struct find_convertible_requirable_property : \
  1843. detail::supportable_properties< \
  1844. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  1845. find_convertible_requirable_property<T> {}; \
  1846. \
  1847. template <typename Property> \
  1848. any_executor require(const Property& p, \
  1849. typename enable_if< \
  1850. find_convertible_requirable_property<Property>::value \
  1851. >::type* = 0) const \
  1852. { \
  1853. typedef find_convertible_requirable_property<Property> found; \
  1854. return prop_fns_[found::index].require(object_fns_->target(*this), \
  1855. &static_cast<const typename found::type&>(p)); \
  1856. } \
  1857. \
  1858. template <typename T> \
  1859. struct find_convertible_preferable_property : \
  1860. detail::supportable_properties< \
  1861. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  1862. find_convertible_preferable_property<T> {}; \
  1863. \
  1864. template <typename Property> \
  1865. any_executor prefer(const Property& p, \
  1866. typename enable_if< \
  1867. find_convertible_preferable_property<Property>::value \
  1868. >::type* = 0) const \
  1869. { \
  1870. typedef find_convertible_preferable_property<Property> found; \
  1871. return prop_fns_[found::index].prefer(object_fns_->target(*this), \
  1872. &static_cast<const typename found::type&>(p)); \
  1873. } \
  1874. \
  1875. template <typename Ex> \
  1876. static const prop_fns<any_executor>* prop_fns_table() \
  1877. { \
  1878. static const prop_fns<any_executor> fns[] = \
  1879. { \
  1880. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \
  1881. }; \
  1882. return fns; \
  1883. } \
  1884. \
  1885. const prop_fns<any_executor>* prop_fns_; \
  1886. typedef detail::supportable_properties<0, \
  1887. void(BOOST_ASIO_VARIADIC_TARGS(n))> supportable_properties_type; \
  1888. }; \
  1889. \
  1890. template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  1891. inline void swap(any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>& a, \
  1892. any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>& b) BOOST_ASIO_NOEXCEPT \
  1893. { \
  1894. return a.swap(b); \
  1895. } \
  1896. /**/
  1897. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ANY_EXECUTOR_DEF)
  1898. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_DEF
  1899. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS
  1900. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS
  1901. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1
  1902. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2
  1903. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3
  1904. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4
  1905. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5
  1906. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6
  1907. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7
  1908. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8
  1909. #endif // if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1910. } // namespace execution
  1911. namespace traits {
  1912. #if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  1913. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1914. template <typename... SupportableProperties>
  1915. struct equality_comparable<execution::any_executor<SupportableProperties...> >
  1916. {
  1917. static const bool is_valid = true;
  1918. static const bool is_noexcept = true;
  1919. };
  1920. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1921. template <>
  1922. struct equality_comparable<execution::any_executor<> >
  1923. {
  1924. static const bool is_valid = true;
  1925. static const bool is_noexcept = true;
  1926. };
  1927. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF(n) \
  1928. template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  1929. struct equality_comparable< \
  1930. execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)> > \
  1931. { \
  1932. static const bool is_valid = true; \
  1933. static const bool is_noexcept = true; \
  1934. }; \
  1935. /**/
  1936. BOOST_ASIO_VARIADIC_GENERATE(
  1937. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF)
  1938. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF
  1939. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1940. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
  1941. #if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  1942. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1943. template <typename F, typename... SupportableProperties>
  1944. struct execute_member<execution::any_executor<SupportableProperties...>, F>
  1945. {
  1946. static const bool is_valid = true;
  1947. static const bool is_noexcept = false;
  1948. typedef void result_type;
  1949. };
  1950. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1951. template <typename F>
  1952. struct execute_member<execution::any_executor<>, F>
  1953. {
  1954. static const bool is_valid = true;
  1955. static const bool is_noexcept = false;
  1956. typedef void result_type;
  1957. };
  1958. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF(n) \
  1959. template <typename F, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  1960. struct execute_member< \
  1961. execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>, F> \
  1962. { \
  1963. static const bool is_valid = true; \
  1964. static const bool is_noexcept = false; \
  1965. typedef void result_type; \
  1966. }; \
  1967. /**/
  1968. BOOST_ASIO_VARIADIC_GENERATE(
  1969. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF)
  1970. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF
  1971. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1972. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
  1973. #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  1974. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1975. template <typename Prop, typename... SupportableProperties>
  1976. struct query_member<
  1977. execution::any_executor<SupportableProperties...>, Prop,
  1978. typename enable_if<
  1979. execution::detail::supportable_properties<
  1980. 0, void(SupportableProperties...)>::template
  1981. find_convertible_property<Prop>::value
  1982. >::type>
  1983. {
  1984. static const bool is_valid = true;
  1985. static const bool is_noexcept = false;
  1986. typedef typename execution::detail::supportable_properties<
  1987. 0, void(SupportableProperties...)>::template
  1988. find_convertible_property<Prop>::query_result_type result_type;
  1989. };
  1990. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  1991. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF(n) \
  1992. template <typename Prop, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  1993. struct query_member< \
  1994. execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>, Prop, \
  1995. typename enable_if< \
  1996. execution::detail::supportable_properties< \
  1997. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  1998. find_convertible_property<Prop>::value \
  1999. >::type> \
  2000. { \
  2001. static const bool is_valid = true; \
  2002. static const bool is_noexcept = false; \
  2003. typedef typename execution::detail::supportable_properties< \
  2004. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  2005. find_convertible_property<Prop>::query_result_type result_type; \
  2006. }; \
  2007. /**/
  2008. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF)
  2009. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF
  2010. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2011. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
  2012. #if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  2013. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2014. template <typename Prop, typename... SupportableProperties>
  2015. struct require_member<
  2016. execution::any_executor<SupportableProperties...>, Prop,
  2017. typename enable_if<
  2018. execution::detail::supportable_properties<
  2019. 0, void(SupportableProperties...)>::template
  2020. find_convertible_requirable_property<Prop>::value
  2021. >::type>
  2022. {
  2023. static const bool is_valid = true;
  2024. static const bool is_noexcept = false;
  2025. typedef execution::any_executor<SupportableProperties...> result_type;
  2026. };
  2027. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2028. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF(n) \
  2029. template <typename Prop, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  2030. struct require_member< \
  2031. execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>, Prop, \
  2032. typename enable_if< \
  2033. execution::detail::supportable_properties< \
  2034. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  2035. find_convertible_requirable_property<Prop>::value \
  2036. >::type> \
  2037. { \
  2038. static const bool is_valid = true; \
  2039. static const bool is_noexcept = false; \
  2040. typedef execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)> result_type; \
  2041. }; \
  2042. /**/
  2043. BOOST_ASIO_VARIADIC_GENERATE(
  2044. BOOST_ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF)
  2045. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF
  2046. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2047. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
  2048. #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
  2049. #if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2050. template <typename Prop, typename... SupportableProperties>
  2051. struct prefer_member<
  2052. execution::any_executor<SupportableProperties...>, Prop,
  2053. typename enable_if<
  2054. execution::detail::supportable_properties<
  2055. 0, void(SupportableProperties...)>::template
  2056. find_convertible_preferable_property<Prop>::value
  2057. >::type>
  2058. {
  2059. static const bool is_valid = true;
  2060. static const bool is_noexcept = false;
  2061. typedef execution::any_executor<SupportableProperties...> result_type;
  2062. };
  2063. #else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2064. #define BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF(n) \
  2065. template <typename Prop, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
  2066. struct prefer_member< \
  2067. execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)>, Prop, \
  2068. typename enable_if< \
  2069. execution::detail::supportable_properties< \
  2070. 0, void(BOOST_ASIO_VARIADIC_TARGS(n))>::template \
  2071. find_convertible_preferable_property<Prop>::value \
  2072. >::type> \
  2073. { \
  2074. static const bool is_valid = true; \
  2075. static const bool is_noexcept = false; \
  2076. typedef execution::any_executor<BOOST_ASIO_VARIADIC_TARGS(n)> result_type; \
  2077. }; \
  2078. /**/
  2079. BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF)
  2080. #undef BOOST_ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF
  2081. #endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
  2082. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
  2083. } // namespace traits
  2084. #endif // defined(GENERATING_DOCUMENTATION)
  2085. } // namespace asio
  2086. } // namespace boost
  2087. #include <boost/asio/detail/pop_options.hpp>
  2088. #endif // BOOST_ASIO_EXECUTION_ANY_EXECUTOR_HPP