variant.hpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460
  1. //-----------------------------------------------------------------------------
  2. // boost variant/variant.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2002-2003 Eric Friedman, Itay Maman
  7. // Copyright (c) 2012-2013 Antony Polukhin
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. // Thanks to Adam Romanek for providing patches for exception-disabled env.
  13. #ifndef BOOST_VARIANT_VARIANT_HPP
  14. #define BOOST_VARIANT_VARIANT_HPP
  15. #include <cstddef> // for std::size_t
  16. #include <new> // for placement new
  17. #if !defined(BOOST_NO_TYPEID)
  18. #include <typeinfo> // for typeid, std::type_info
  19. #endif // BOOST_NO_TYPEID
  20. #include "boost/variant/detail/config.hpp"
  21. #include "boost/mpl/aux_/config/eti.hpp"
  22. #include "boost/mpl/aux_/value_wknd.hpp"
  23. #include "boost/variant/variant_fwd.hpp"
  24. #include "boost/variant/detail/backup_holder.hpp"
  25. #include "boost/variant/detail/enable_recursive_fwd.hpp"
  26. #include "boost/variant/detail/forced_return.hpp"
  27. #include "boost/variant/detail/initializer.hpp"
  28. #include "boost/variant/detail/make_variant_list.hpp"
  29. #include "boost/variant/detail/over_sequence.hpp"
  30. #include "boost/variant/detail/visitation_impl.hpp"
  31. #include "boost/variant/detail/hash_variant.hpp"
  32. #include "boost/variant/detail/generic_result_type.hpp"
  33. #include "boost/variant/detail/move.hpp"
  34. #include "boost/detail/no_exceptions_support.hpp"
  35. #include "boost/detail/reference_content.hpp"
  36. #include "boost/aligned_storage.hpp"
  37. #include "boost/blank.hpp"
  38. #include "boost/math/common_factor_ct.hpp"
  39. #include "boost/static_assert.hpp"
  40. #include "boost/preprocessor/cat.hpp"
  41. #include "boost/preprocessor/repeat.hpp"
  42. #include "boost/type_traits/alignment_of.hpp"
  43. #include "boost/type_traits/add_const.hpp"
  44. #include "boost/type_traits/has_nothrow_constructor.hpp"
  45. #include "boost/type_traits/has_nothrow_copy.hpp"
  46. #include "boost/type_traits/is_nothrow_move_constructible.hpp"
  47. #include "boost/type_traits/is_const.hpp"
  48. #include "boost/type_traits/is_same.hpp"
  49. #include "boost/type_traits/is_rvalue_reference.hpp"
  50. #include "boost/utility/enable_if.hpp"
  51. #include "boost/utility/declval.hpp"
  52. #include "boost/variant/recursive_wrapper_fwd.hpp"
  53. #include "boost/variant/static_visitor.hpp"
  54. #include "boost/mpl/assert.hpp"
  55. #include "boost/mpl/begin_end.hpp"
  56. #include "boost/mpl/bool.hpp"
  57. #include "boost/mpl/deref.hpp"
  58. #include "boost/mpl/empty.hpp"
  59. #include "boost/mpl/eval_if.hpp"
  60. #include "boost/mpl/find_if.hpp"
  61. #include "boost/mpl/fold.hpp"
  62. #include "boost/mpl/front.hpp"
  63. #include "boost/mpl/identity.hpp"
  64. #include "boost/mpl/if.hpp"
  65. #include "boost/mpl/int.hpp"
  66. #include "boost/mpl/is_sequence.hpp"
  67. #include "boost/mpl/iterator_range.hpp"
  68. #include "boost/mpl/iter_fold_if.hpp"
  69. #include "boost/mpl/logical.hpp"
  70. #include "boost/mpl/max_element.hpp"
  71. #include "boost/mpl/next.hpp"
  72. #include "boost/mpl/not.hpp"
  73. #include "boost/mpl/pair.hpp"
  74. #include "boost/mpl/protect.hpp"
  75. #include "boost/mpl/push_front.hpp"
  76. #include "boost/mpl/same_as.hpp"
  77. #include "boost/mpl/size_t.hpp"
  78. #include "boost/mpl/sizeof.hpp"
  79. #include "boost/mpl/transform.hpp"
  80. ///////////////////////////////////////////////////////////////////////////////
  81. // Implementation Macros:
  82. //
  83. // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
  84. // Defined in boost/variant/detail/visitation_impl.hpp.
  85. //
  86. // BOOST_VARIANT_MINIMIZE_SIZE
  87. // When #defined, implementation employs all known means to minimize the
  88. // size of variant obje cts. However, often unsuccessful due to alignment
  89. // issues, and potentially harmful to runtime speed, so not enabled by
  90. // default. (TODO: Investigate further.)
  91. #if defined(BOOST_VARIANT_MINIMIZE_SIZE)
  92. # include <climits> // for SCHAR_MAX
  93. # include "boost/mpl/eval_if.hpp"
  94. # include "boost/mpl/equal_to.hpp"
  95. # include "boost/mpl/identity.hpp"
  96. # include "boost/mpl/int.hpp"
  97. # include "boost/mpl/if.hpp"
  98. # include "boost/mpl/less.hpp"
  99. # include "boost/mpl/long.hpp"
  100. # include "boost/mpl/O1_size.hpp"
  101. #endif
  102. namespace boost {
  103. namespace detail { namespace variant {
  104. ///////////////////////////////////////////////////////////////////////////////
  105. // (detail) metafunction max_value
  106. //
  107. // Finds the maximum value of the unary metafunction F over Sequence.
  108. //
  109. template <typename Sequence, typename F>
  110. struct max_value
  111. {
  112. private: // helpers, for metafunction result (below)
  113. typedef typename mpl::transform1<Sequence, F>::type transformed_;
  114. typedef typename mpl::max_element<transformed_
  115. >::type max_it;
  116. public: // metafunction result
  117. typedef typename mpl::deref<max_it>::type
  118. type;
  119. };
  120. struct add_alignment
  121. {
  122. template <typename State, typename Item>
  123. struct apply
  124. : mpl::size_t<
  125. ::boost::math::static_lcm<
  126. BOOST_MPL_AUX_VALUE_WKND(State)::value
  127. , ::boost::alignment_of<Item>::value
  128. >::value
  129. >
  130. {};
  131. };
  132. ///////////////////////////////////////////////////////////////////////////////
  133. // (detail) metafunction find_fallback_type
  134. //
  135. // Provides a fallback (i.e., nothrow default-constructible) type from the
  136. // specified sequence, or no_fallback_type if not found.
  137. //
  138. // This implementation is designed to prefer boost::blank over other potential
  139. // fallback types, regardless of its position in the specified sequence.
  140. //
  141. class no_fallback_type;
  142. struct find_fallback_type_pred
  143. {
  144. template <typename Iterator>
  145. struct apply
  146. {
  147. private:
  148. typedef typename mpl::deref<Iterator>::type t_;
  149. public:
  150. typedef mpl::not_< has_nothrow_constructor<t_> > type;
  151. };
  152. };
  153. template <typename Types>
  154. struct find_fallback_type
  155. {
  156. private: // helpers, for metafunction result (below)
  157. typedef typename mpl::end<Types>::type end_it;
  158. // [Find the first suitable fallback type...]
  159. typedef typename mpl::iter_fold_if<
  160. Types
  161. , mpl::int_<0>, mpl::protect< mpl::next<> >
  162. , mpl::protect< find_fallback_type_pred >
  163. >::type first_result_;
  164. typedef typename first_result_::first first_result_index;
  165. typedef typename first_result_::second first_result_it;
  166. // [...now search the rest of the sequence for boost::blank...]
  167. typedef typename mpl::iter_fold_if<
  168. mpl::iterator_range< first_result_it,end_it >
  169. , first_result_index, mpl::protect< mpl::next<> >
  170. , mpl::protect< mpl::not_same_as<boost::blank> >
  171. >::type second_result_;
  172. typedef typename second_result_::second second_result_it;
  173. public: // metafunction result
  174. // [...and return the results of the search:]
  175. typedef typename mpl::eval_if<
  176. is_same< second_result_it,end_it >
  177. , mpl::if_<
  178. is_same< first_result_it,end_it >
  179. , mpl::pair< no_fallback_type,no_fallback_type >
  180. , first_result_
  181. >
  182. , mpl::identity< second_result_ >
  183. >::type type;
  184. };
  185. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  186. template<>
  187. struct find_fallback_type<int>
  188. {
  189. typedef mpl::pair< no_fallback_type,no_fallback_type > type;
  190. };
  191. #endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
  192. #ifndef BOOST_NO_CXX11_NOEXCEPT
  193. ///////////////////////////////////////////////////////////////////////////////
  194. // (detail) metafunction is_variant_move_noexcept
  195. //
  196. // Returns true_type if all the types are nothrow move constructible.
  197. //
  198. template <class Types>
  199. struct is_variant_move_noexcept {
  200. typedef typename boost::mpl::find_if<
  201. Types, mpl::not_<boost::is_nothrow_move_constructible<boost::mpl::_1> >
  202. >::type iterator_t;
  203. typedef typename boost::mpl::end<Types>::type end_t;
  204. typedef typename boost::is_same<
  205. iterator_t, end_t
  206. >::type type;
  207. };
  208. #endif // BOOST_NO_CXX11_NOEXCEPT
  209. ///////////////////////////////////////////////////////////////////////////////
  210. // (detail) metafunction make_storage
  211. //
  212. // Provides an aligned storage type capable of holding any of the types
  213. // specified in the given type-sequence.
  214. //
  215. template <typename Types, typename NeverUsesBackupFlag>
  216. struct make_storage
  217. {
  218. private: // helpers, for metafunction result (below)
  219. typedef typename mpl::eval_if<
  220. NeverUsesBackupFlag
  221. , mpl::identity< Types >
  222. , mpl::push_front<
  223. Types, backup_holder<void*>
  224. >
  225. >::type types;
  226. typedef typename max_value<
  227. types, mpl::sizeof_<mpl::_1>
  228. >::type max_size;
  229. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
  230. typedef typename mpl::fold<
  231. types
  232. , mpl::size_t<1>
  233. , add_alignment
  234. >::type max_alignment;
  235. #else // borland
  236. // temporary workaround -- use maximal alignment
  237. typedef mpl::size_t< -1 > max_alignment;
  238. #endif // borland workaround
  239. public: // metafunction result
  240. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  241. typedef ::boost::aligned_storage<
  242. BOOST_MPL_AUX_VALUE_WKND(max_size)::value
  243. , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
  244. > type;
  245. #else // MSVC7 and below
  246. BOOST_STATIC_CONSTANT(std::size_t, msvc_max_size_c = max_size::value);
  247. BOOST_STATIC_CONSTANT(std::size_t, msvc_max_alignment_c = max_alignment::value);
  248. typedef ::boost::aligned_storage<
  249. msvc_max_size_c
  250. , msvc_max_alignment_c
  251. > type;
  252. #endif // MSVC workaround
  253. };
  254. #if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
  255. template<>
  256. struct make_storage<int,int>
  257. {
  258. typedef int type;
  259. };
  260. #endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
  261. ///////////////////////////////////////////////////////////////////////////////
  262. // (detail) class destroyer
  263. //
  264. // Internal visitor that destroys the value it visits.
  265. //
  266. struct destroyer
  267. : public static_visitor<>
  268. {
  269. public: // visitor interfaces
  270. template <typename T>
  271. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  272. internal_visit(T& operand, int) const
  273. {
  274. operand.~T();
  275. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) || \
  276. BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  277. operand; // suppresses warnings
  278. #endif
  279. BOOST_VARIANT_AUX_RETURN_VOID;
  280. }
  281. };
  282. ///////////////////////////////////////////////////////////////////////////////
  283. // (detail) class template known_get
  284. //
  285. // Visitor that returns a reference to content of the specified type.
  286. //
  287. // Precondition: visited variant MUST contain logical content of type T.
  288. //
  289. template <typename T>
  290. class known_get
  291. : public static_visitor<T&>
  292. {
  293. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  294. public: // visitor interface
  295. T& operator()(T& operand) const BOOST_NOEXCEPT
  296. {
  297. return operand;
  298. }
  299. #if defined BOOST_MSVC
  300. # pragma warning( push )
  301. # pragma warning( disable : 4702 ) // unreachable code
  302. #endif
  303. template <typename U>
  304. T& operator()(U&) const
  305. {
  306. // logical error to be here: see precondition above
  307. BOOST_ASSERT(false);
  308. return ::boost::detail::variant::forced_return< T& >();
  309. }
  310. #if defined BOOST_MSVC
  311. # pragma warning( pop )
  312. #endif
  313. #else // MSVC6
  314. private: // helpers, for visitor interface (below)
  315. T& execute(T& operand, mpl::true_) const
  316. {
  317. return operand;
  318. }
  319. template <typename U>
  320. T& execute(U& operand, mpl::false_) const
  321. {
  322. // logical error to be here: see precondition above
  323. BOOST_ASSERT(false);
  324. return ::boost::detail::variant::forced_return< T& >();
  325. }
  326. public: // visitor interface
  327. template <typename U>
  328. T& operator()(U& operand) const
  329. {
  330. typedef typename is_same< U,T >::type
  331. U_is_T;
  332. return execute(operand, U_is_T());
  333. }
  334. #endif // MSVC6 workaround
  335. };
  336. ///////////////////////////////////////////////////////////////////////////////
  337. // (detail) class copy_into
  338. //
  339. // Internal visitor that copies the value it visits into the given buffer.
  340. //
  341. class copy_into
  342. : public static_visitor<>
  343. {
  344. private: // representation
  345. void* storage_;
  346. public: // structors
  347. explicit copy_into(void* storage) BOOST_NOEXCEPT
  348. : storage_(storage)
  349. {
  350. }
  351. public: // internal visitor interface
  352. template <typename T>
  353. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  354. internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
  355. {
  356. new(storage_) T( operand.get() );
  357. BOOST_VARIANT_AUX_RETURN_VOID;
  358. }
  359. template <typename T>
  360. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  361. internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
  362. {
  363. new(storage_) T( operand.get() );
  364. BOOST_VARIANT_AUX_RETURN_VOID;
  365. }
  366. template <typename T>
  367. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  368. internal_visit(const T& operand, int) const
  369. {
  370. new(storage_) T(operand);
  371. BOOST_VARIANT_AUX_RETURN_VOID;
  372. }
  373. };
  374. ///////////////////////////////////////////////////////////////////////////////
  375. // (detail) class move_into
  376. //
  377. // Internal visitor that moves the value it visits into the given buffer.
  378. //
  379. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  380. class move_into
  381. : public static_visitor<>
  382. {
  383. private: // representation
  384. void* storage_;
  385. public: // structors
  386. explicit move_into(void* storage) BOOST_NOEXCEPT
  387. : storage_(storage)
  388. {
  389. }
  390. public: // internal visitor interface
  391. template <typename T>
  392. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  393. internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
  394. {
  395. new(storage_) T( ::boost::detail::variant::move(operand.get()) );
  396. BOOST_VARIANT_AUX_RETURN_VOID;
  397. }
  398. template <typename T>
  399. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  400. internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval<T>())))
  401. {
  402. new(storage_) T(::boost::detail::variant::move(operand));
  403. BOOST_VARIANT_AUX_RETURN_VOID;
  404. }
  405. };
  406. #endif
  407. ///////////////////////////////////////////////////////////////////////////////
  408. // (detail) class assign_storage
  409. //
  410. // Internal visitor that assigns the given storage (which must be a
  411. // constructed value of the same type) to the value it visits.
  412. //
  413. struct assign_storage
  414. : public static_visitor<>
  415. {
  416. private: // representation
  417. const void* rhs_storage_;
  418. public: // structors
  419. explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT
  420. : rhs_storage_(rhs_storage)
  421. {
  422. }
  423. public: // internal visitor interfaces
  424. template <typename T>
  425. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  426. internal_visit(backup_holder<T>& lhs_content, long) const
  427. {
  428. lhs_content.get()
  429. = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
  430. BOOST_VARIANT_AUX_RETURN_VOID;
  431. }
  432. template <typename T>
  433. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  434. internal_visit(const backup_holder<T>& lhs_content, long) const
  435. {
  436. lhs_content.get()
  437. = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
  438. BOOST_VARIANT_AUX_RETURN_VOID;
  439. }
  440. template <typename T>
  441. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  442. internal_visit(T& lhs_content, int) const
  443. {
  444. // NOTE TO USER :
  445. // Compile error here indicates one of variant's bounded types does
  446. // not meet the requirements of the Assignable concept. Thus,
  447. // variant is not Assignable.
  448. //
  449. // Hint: Are any of the bounded types const-qualified or references?
  450. //
  451. lhs_content = *static_cast< const T* >(rhs_storage_);
  452. BOOST_VARIANT_AUX_RETURN_VOID;
  453. }
  454. };
  455. ///////////////////////////////////////////////////////////////////////////////
  456. // (detail) class move_storage
  457. //
  458. // Internal visitor that moves the given storage (which must be a
  459. // constructed value of the same type) to the value it visits.
  460. //
  461. struct move_storage
  462. : public static_visitor<>
  463. {
  464. private: // representation
  465. void* rhs_storage_;
  466. public: // structors
  467. explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT
  468. : rhs_storage_(rhs_storage)
  469. {
  470. }
  471. public: // internal visitor interfaces
  472. template <typename T>
  473. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  474. internal_visit(backup_holder<T>& lhs_content, long) const
  475. {
  476. lhs_content.get()
  477. = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
  478. BOOST_VARIANT_AUX_RETURN_VOID;
  479. }
  480. template <typename T>
  481. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  482. internal_visit(const backup_holder<T>& lhs_content, long) const
  483. {
  484. lhs_content.get()
  485. = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
  486. BOOST_VARIANT_AUX_RETURN_VOID;
  487. }
  488. template <typename T>
  489. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  490. internal_visit(T& lhs_content, int) const
  491. {
  492. // NOTE TO USER :
  493. // Compile error here indicates one of variant's bounded types does
  494. // not meet the requirements of the Assignable concept. Thus,
  495. // variant is not Assignable.
  496. //
  497. // Hint: Are any of the bounded types const-qualified or references?
  498. //
  499. lhs_content = ::boost::detail::variant::move(*static_cast<T* >(rhs_storage_));
  500. BOOST_VARIANT_AUX_RETURN_VOID;
  501. }
  502. };
  503. ///////////////////////////////////////////////////////////////////////////////
  504. // (detail) class direct_assigner
  505. //
  506. // Generic static visitor that: if and only if the visited value is of the
  507. // specified type, assigns the given value to the visited value and returns
  508. // true; else returns false.
  509. //
  510. template <typename T>
  511. class direct_assigner
  512. : public static_visitor<bool>
  513. {
  514. private: // representation
  515. const T& rhs_;
  516. public: // structors
  517. explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT
  518. : rhs_(rhs)
  519. {
  520. }
  521. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  522. public: // visitor interface
  523. bool operator()(T& lhs)
  524. {
  525. lhs = rhs_;
  526. return true;
  527. }
  528. template <typename U>
  529. bool operator()(U&) BOOST_NOEXCEPT
  530. {
  531. return false;
  532. }
  533. #else // MSVC6
  534. private: // helpers, for visitor interface (below)
  535. bool execute(T& lhs, mpl::true_)
  536. {
  537. lhs = rhs_;
  538. return true;
  539. }
  540. template <typename U>
  541. bool execute(U&, mpl::false_)
  542. {
  543. return false;
  544. }
  545. public: // visitor interface
  546. template <typename U>
  547. bool operator()(U& lhs)
  548. {
  549. typedef typename is_same<U,T>::type U_is_T;
  550. return execute(lhs, U_is_T());
  551. }
  552. #endif // MSVC6 workaround
  553. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  554. private:
  555. // silence MSVC warning C4512: assignment operator could not be generated
  556. direct_assigner& operator= (direct_assigner const&);
  557. #endif
  558. };
  559. ///////////////////////////////////////////////////////////////////////////////
  560. // (detail) class direct_mover
  561. //
  562. // Generic static visitor that: if and only if the visited value is of the
  563. // specified type, move assigns the given value to the visited value and returns
  564. // true; else returns false.
  565. //
  566. template <typename T>
  567. class direct_mover
  568. : public static_visitor<bool>
  569. {
  570. private: // representation
  571. T& rhs_;
  572. public: // structors
  573. explicit direct_mover(T& rhs) BOOST_NOEXCEPT
  574. : rhs_(rhs)
  575. {
  576. }
  577. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  578. public: // visitor interface
  579. bool operator()(T& lhs)
  580. {
  581. lhs = ::boost::detail::variant::move(rhs_);
  582. return true;
  583. }
  584. template <typename U>
  585. bool operator()(U&) BOOST_NOEXCEPT
  586. {
  587. return false;
  588. }
  589. #else // MSVC6
  590. public: // visitor interface
  591. template <typename U>
  592. bool operator()(U& lhs)
  593. {
  594. // MSVC6 can not use direct_mover class
  595. return direct_assigner(rhs_)(lhs);
  596. }
  597. #endif // MSVC6 workaround
  598. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  599. private:
  600. // silence MSVC warning C4512: assignment operator could not be generated
  601. direct_mover& operator= (direct_mover const&);
  602. #endif
  603. };
  604. ///////////////////////////////////////////////////////////////////////////////
  605. // (detail) class backup_assigner
  606. //
  607. // Internal visitor that "assigns" the given value to the visited value,
  608. // using backup to recover if the destroy-copy sequence fails.
  609. //
  610. // NOTE: This needs to be a friend of variant, as it needs access to
  611. // indicate_which, indicate_backup_which, etc.
  612. //
  613. template <typename Variant>
  614. class backup_assigner
  615. : public static_visitor<>
  616. {
  617. private: // representation
  618. Variant& lhs_;
  619. int rhs_which_;
  620. const void* rhs_content_;
  621. void (*copy_rhs_content_)(void*, const void*);
  622. public: // structors
  623. template<class RhsT>
  624. backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
  625. : lhs_(lhs)
  626. , rhs_which_(rhs_which)
  627. , rhs_content_(&rhs_content)
  628. , copy_rhs_content_(&construct_impl<RhsT>)
  629. {
  630. }
  631. private: // helpers, for visitor interface (below)
  632. template<class RhsT>
  633. static void construct_impl(void* addr, const void* obj)
  634. {
  635. new(addr) RhsT(*static_cast<const RhsT*>(obj));
  636. }
  637. template <typename LhsT>
  638. void backup_assign_impl(
  639. LhsT& lhs_content
  640. , mpl::true_ // is_nothrow_move_constructible
  641. )
  642. {
  643. // Move lhs content to backup...
  644. LhsT backup_lhs_content(
  645. ::boost::detail::variant::move(lhs_content)
  646. ); // nothrow
  647. // ...destroy lhs content...
  648. lhs_content.~LhsT(); // nothrow
  649. BOOST_TRY
  650. {
  651. // ...and attempt to copy rhs content into lhs storage:
  652. copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
  653. }
  654. BOOST_CATCH (...)
  655. {
  656. // In case of failure, restore backup content to lhs storage...
  657. new(lhs_.storage_.address())
  658. LhsT(
  659. ::boost::detail::variant::move(backup_lhs_content)
  660. ); // nothrow
  661. // ...and rethrow:
  662. BOOST_RETHROW;
  663. }
  664. BOOST_CATCH_END
  665. // In case of success, indicate new content type:
  666. lhs_.indicate_which(rhs_which_); // nothrow
  667. }
  668. template <typename LhsT>
  669. void backup_assign_impl(
  670. LhsT& lhs_content
  671. , mpl::false_ // is_nothrow_move_constructible
  672. )
  673. {
  674. // Backup lhs content...
  675. LhsT* backup_lhs_ptr = new LhsT(lhs_content);
  676. // ...destroy lhs content...
  677. lhs_content.~LhsT(); // nothrow
  678. BOOST_TRY
  679. {
  680. // ...and attempt to copy rhs content into lhs storage:
  681. copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
  682. }
  683. BOOST_CATCH (...)
  684. {
  685. // In case of failure, copy backup pointer to lhs storage...
  686. new(lhs_.storage_.address())
  687. backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
  688. // ...indicate now using backup...
  689. lhs_.indicate_backup_which( lhs_.which() ); // nothrow
  690. // ...and rethrow:
  691. BOOST_RETHROW;
  692. }
  693. BOOST_CATCH_END
  694. // In case of success, indicate new content type...
  695. lhs_.indicate_which(rhs_which_); // nothrow
  696. // ...and delete backup:
  697. delete backup_lhs_ptr; // nothrow
  698. }
  699. public: // visitor interface
  700. template <typename LhsT>
  701. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  702. internal_visit(LhsT& lhs_content, int)
  703. {
  704. typedef typename is_nothrow_move_constructible<LhsT>::type
  705. nothrow_move;
  706. backup_assign_impl( lhs_content, nothrow_move() );
  707. BOOST_VARIANT_AUX_RETURN_VOID;
  708. }
  709. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  710. private:
  711. // silence MSVC warning C4512: assignment operator could not be generated
  712. backup_assigner& operator= (backup_assigner const&);
  713. #endif
  714. };
  715. ///////////////////////////////////////////////////////////////////////////////
  716. // (detail) class swap_with
  717. //
  718. // Visitor that swaps visited value with content of given variant.
  719. //
  720. // Precondition: Given variant MUST have same logical type as visited value.
  721. //
  722. template <typename Variant>
  723. struct swap_with
  724. : public static_visitor<>
  725. {
  726. private: // representation
  727. Variant& toswap_;
  728. public: // structors
  729. explicit swap_with(Variant& toswap)
  730. : toswap_(toswap)
  731. {
  732. }
  733. public: // internal visitor interfaces
  734. template <typename T>
  735. void operator()(T& operand) const
  736. {
  737. // Since the precondition ensures types are same, get T...
  738. known_get<T> getter;
  739. T& other = toswap_.apply_visitor(getter);
  740. // ...and swap:
  741. ::boost::detail::variant::move_swap( operand, other );
  742. }
  743. private:
  744. swap_with& operator=(const swap_with&);
  745. };
  746. ///////////////////////////////////////////////////////////////////////////////
  747. // (detail) class reflect
  748. //
  749. // Generic static visitor that performs a typeid on the value it visits.
  750. //
  751. #if !defined(BOOST_NO_TYPEID)
  752. class reflect
  753. : public static_visitor<const std::type_info&>
  754. {
  755. public: // visitor interfaces
  756. template <typename T>
  757. const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
  758. {
  759. return typeid(T);
  760. }
  761. };
  762. #endif // BOOST_NO_TYPEID
  763. ///////////////////////////////////////////////////////////////////////////////
  764. // (detail) class comparer
  765. //
  766. // Generic static visitor that compares the content of the given lhs variant
  767. // with the visited rhs content using Comp.
  768. //
  769. // Precondition: lhs.which() == rhs.which()
  770. //
  771. template <typename Variant, typename Comp>
  772. class comparer
  773. : public static_visitor<bool>
  774. {
  775. private: // representation
  776. const Variant& lhs_;
  777. public: // structors
  778. explicit comparer(const Variant& lhs) BOOST_NOEXCEPT
  779. : lhs_(lhs)
  780. {
  781. }
  782. public: // visitor interfaces
  783. template <typename T>
  784. bool operator()(const T& rhs_content) const
  785. {
  786. // Since the precondition ensures lhs and rhs types are same, get T...
  787. known_get<const T> getter;
  788. const T& lhs_content = lhs_.apply_visitor(getter);
  789. // ...and compare lhs and rhs contents:
  790. return Comp()(lhs_content, rhs_content);
  791. }
  792. private:
  793. comparer& operator=(const comparer&);
  794. };
  795. ///////////////////////////////////////////////////////////////////////////////
  796. // (detail) class equal_comp
  797. //
  798. // Generic function object compares lhs with rhs using operator==.
  799. //
  800. struct equal_comp
  801. {
  802. template <typename T>
  803. bool operator()(const T& lhs, const T& rhs) const
  804. {
  805. return lhs == rhs;
  806. }
  807. };
  808. ///////////////////////////////////////////////////////////////////////////////
  809. // (detail) class less_comp
  810. //
  811. // Generic function object compares lhs with rhs using operator<.
  812. //
  813. struct less_comp
  814. {
  815. template <typename T>
  816. bool operator()(const T& lhs, const T& rhs) const
  817. {
  818. return lhs < rhs;
  819. }
  820. };
  821. ///////////////////////////////////////////////////////////////////////////////
  822. // (detail) class template invoke_visitor
  823. //
  824. // Internal visitor that invokes the given visitor using:
  825. // * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
  826. // * for all other values, the value itself.
  827. //
  828. template <typename Visitor>
  829. class invoke_visitor
  830. {
  831. private: // representation
  832. Visitor& visitor_;
  833. public: // visitor typedefs
  834. typedef typename Visitor::result_type
  835. result_type;
  836. public: // structors
  837. explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT
  838. : visitor_(visitor)
  839. {
  840. }
  841. #if !defined(BOOST_NO_VOID_RETURNS)
  842. public: // internal visitor interfaces
  843. template <typename T>
  844. result_type internal_visit(T& operand, int)
  845. {
  846. return visitor_(operand);
  847. }
  848. # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
  849. template <typename T>
  850. result_type internal_visit(const T& operand, int)
  851. {
  852. return visitor_(operand);
  853. }
  854. # endif
  855. #else // defined(BOOST_NO_VOID_RETURNS)
  856. private: // helpers, for internal visitor interfaces (below)
  857. template <typename T>
  858. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  859. visit_impl(T& operand, mpl::false_)
  860. {
  861. return visitor_(operand);
  862. }
  863. template <typename T>
  864. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  865. visit_impl(T& operand, mpl::true_)
  866. {
  867. visitor_(operand);
  868. BOOST_VARIANT_AUX_RETURN_VOID;
  869. }
  870. public: // internal visitor interfaces
  871. template <typename T>
  872. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  873. internal_visit(T& operand, int)
  874. {
  875. typedef typename is_same<result_type, void>::type
  876. has_void_result_type;
  877. return visit_impl(operand, has_void_result_type());
  878. }
  879. #endif // BOOST_NO_VOID_RETURNS) workaround
  880. public: // internal visitor interfaces, cont.
  881. template <typename T>
  882. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  883. internal_visit(boost::recursive_wrapper<T>& operand, long)
  884. {
  885. return internal_visit( operand.get(), 1L );
  886. }
  887. template <typename T>
  888. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  889. internal_visit(const boost::recursive_wrapper<T>& operand, long)
  890. {
  891. return internal_visit( operand.get(), 1L );
  892. }
  893. template <typename T>
  894. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  895. internal_visit(boost::detail::reference_content<T>& operand, long)
  896. {
  897. return internal_visit( operand.get(), 1L );
  898. }
  899. template <typename T>
  900. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  901. internal_visit(const boost::detail::reference_content<T>& operand, long)
  902. {
  903. return internal_visit( operand.get(), 1L );
  904. }
  905. template <typename T>
  906. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  907. internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
  908. {
  909. return internal_visit( operand.get(), 1L );
  910. }
  911. template <typename T>
  912. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
  913. internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
  914. {
  915. return internal_visit( operand.get(), 1L );
  916. }
  917. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  918. private:
  919. // silence MSVC warning C4512: assignment operator could not be generated
  920. invoke_visitor& operator= (invoke_visitor const&);
  921. #endif
  922. };
  923. }} // namespace detail::variant
  924. ///////////////////////////////////////////////////////////////////////////////
  925. // class template variant (concept inspired by Andrei Alexandrescu)
  926. //
  927. // See docs and boost/variant/variant_fwd.hpp for more information.
  928. //
  929. template <
  930. typename T0_
  931. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
  932. >
  933. class variant
  934. {
  935. private: // helpers, for typedefs (below)
  936. typedef variant wknd_self_t;
  937. struct is_recursive_
  938. : detail::variant::is_recursive_flag<T0_>
  939. {
  940. };
  941. typedef typename mpl::eval_if<
  942. is_recursive_
  943. , T0_
  944. , mpl::identity< T0_ >
  945. >::type unwrapped_T0_;
  946. struct is_sequence_based_
  947. : detail::variant::is_over_sequence<unwrapped_T0_>
  948. {
  949. };
  950. #if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
  951. private: // helpers, for typedefs (below)
  952. typedef typename mpl::eval_if<
  953. is_sequence_based_
  954. , unwrapped_T0_ // over_sequence<...>::type
  955. , detail::variant::make_variant_list<
  956. unwrapped_T0_
  957. , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
  958. >
  959. >::type specified_types;
  960. BOOST_STATIC_ASSERT((
  961. ::boost::mpl::not_< mpl::empty<specified_types> >::value
  962. ));
  963. typedef typename mpl::eval_if<
  964. is_recursive_
  965. , mpl::transform<
  966. specified_types
  967. , mpl::protect<
  968. detail::variant::quoted_enable_recursive<wknd_self_t>
  969. >
  970. >
  971. , mpl::identity< specified_types >
  972. >::type recursive_enabled_types;
  973. public: // public typedefs
  974. typedef typename mpl::transform<
  975. recursive_enabled_types
  976. , unwrap_recursive<mpl::_1>
  977. >::type types;
  978. private: // internal typedefs
  979. typedef typename mpl::transform<
  980. recursive_enabled_types
  981. , mpl::protect< detail::make_reference_content<> >
  982. >::type internal_types;
  983. typedef typename mpl::front<
  984. internal_types
  985. >::type internal_T0;
  986. #else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
  987. private: // helpers, for typedefs (below)
  988. typedef unwrapped_T0_ T0;
  989. #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
  990. typedef typename mpl::eval_if< \
  991. is_recursive_ \
  992. , detail::variant::enable_recursive< \
  993. BOOST_PP_CAT(T,N) \
  994. , wknd_self_t \
  995. > \
  996. , mpl::identity< BOOST_PP_CAT(T,N) > \
  997. >::type BOOST_PP_CAT(recursive_enabled_T,N); \
  998. /**/
  999. BOOST_PP_REPEAT(
  1000. BOOST_VARIANT_LIMIT_TYPES
  1001. , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
  1002. , _
  1003. )
  1004. #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
  1005. #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \
  1006. typedef typename unwrap_recursive< \
  1007. BOOST_PP_CAT(recursive_enabled_T,N) \
  1008. >::type BOOST_PP_CAT(public_T,N); \
  1009. /**/
  1010. BOOST_PP_REPEAT(
  1011. BOOST_VARIANT_LIMIT_TYPES
  1012. , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
  1013. , _
  1014. )
  1015. #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
  1016. public: // public typedefs
  1017. typedef typename detail::variant::make_variant_list<
  1018. BOOST_VARIANT_ENUM_PARAMS(public_T)
  1019. >::type types;
  1020. private: // helpers, for internal typedefs (below)
  1021. #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \
  1022. typedef detail::make_reference_content< \
  1023. BOOST_PP_CAT(recursive_enabled_T,N) \
  1024. >::type BOOST_PP_CAT(internal_T,N); \
  1025. /**/
  1026. BOOST_PP_REPEAT(
  1027. BOOST_VARIANT_LIMIT_TYPES
  1028. , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
  1029. , _
  1030. )
  1031. #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
  1032. private: // internal typedefs
  1033. typedef typename detail::variant::make_variant_list<
  1034. BOOST_VARIANT_ENUM_PARAMS(internal_T)
  1035. >::type internal_types;
  1036. private: // static precondition assertions
  1037. // NOTE TO USER :
  1038. // variant< type-sequence > syntax is not supported on this compiler!
  1039. //
  1040. BOOST_MPL_ASSERT_NOT(( is_sequence_based_ ));
  1041. #endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
  1042. private: // helpers, for representation (below)
  1043. typedef typename detail::variant::find_fallback_type<
  1044. internal_types
  1045. >::type fallback_type_result_;
  1046. typedef typename fallback_type_result_::first
  1047. fallback_type_index_;
  1048. typedef typename fallback_type_result_::second
  1049. fallback_type_;
  1050. struct has_fallback_type_
  1051. : mpl::not_<
  1052. is_same< fallback_type_, detail::variant::no_fallback_type >
  1053. >
  1054. {
  1055. };
  1056. typedef has_fallback_type_
  1057. never_uses_backup_flag;
  1058. typedef typename detail::variant::make_storage<
  1059. internal_types, never_uses_backup_flag
  1060. >::type storage_t;
  1061. #ifndef BOOST_NO_CXX11_NOEXCEPT
  1062. typedef typename detail::variant::is_variant_move_noexcept<
  1063. internal_types
  1064. > variant_move_noexcept;
  1065. #endif
  1066. private: // helpers, for representation (below)
  1067. // which_ on:
  1068. // * [0, size<internal_types>) indicates stack content
  1069. // * [-size<internal_types>, 0) indicates pointer to heap backup
  1070. // if which_ >= 0:
  1071. // * then which() -> which_
  1072. // * else which() -> -(which_ + 1)
  1073. #if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
  1074. typedef int which_t;
  1075. #else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
  1076. // [if O1_size available, then attempt which_t size optimization...]
  1077. // [select signed char if fewer than SCHAR_MAX types, else signed int:]
  1078. typedef typename mpl::eval_if<
  1079. mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
  1080. , mpl::identity< int >
  1081. , mpl::if_<
  1082. mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
  1083. , signed char
  1084. , int
  1085. >
  1086. >::type which_t;
  1087. #endif // BOOST_VARIANT_MINIMIZE_SIZE switch
  1088. // representation -- private when possible
  1089. #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  1090. private:
  1091. #else
  1092. public:
  1093. #endif
  1094. which_t which_;
  1095. storage_t storage_;
  1096. void indicate_which(int which_arg) BOOST_NOEXCEPT
  1097. {
  1098. which_ = static_cast<which_t>( which_arg );
  1099. }
  1100. void indicate_backup_which(int which_arg) BOOST_NOEXCEPT
  1101. {
  1102. which_ = static_cast<which_t>( -(which_arg + 1) );
  1103. }
  1104. private: // helpers, for queries (below)
  1105. bool using_backup() const BOOST_NOEXCEPT
  1106. {
  1107. return which_ < 0;
  1108. }
  1109. public: // queries
  1110. int which() const BOOST_NOEXCEPT
  1111. {
  1112. // If using heap backup...
  1113. if (using_backup())
  1114. // ...then return adjusted which_:
  1115. return -(which_ + 1);
  1116. // Otherwise, return which_ directly:
  1117. return which_;
  1118. }
  1119. private: // helpers, for structors (below)
  1120. struct initializer
  1121. : BOOST_VARIANT_AUX_INITIALIZER_T(
  1122. recursive_enabled_types, recursive_enabled_T
  1123. )
  1124. {
  1125. };
  1126. void destroy_content()
  1127. {
  1128. detail::variant::destroyer visitor;
  1129. this->internal_apply_visitor(visitor);
  1130. }
  1131. public: // structors
  1132. ~variant() BOOST_NOEXCEPT
  1133. {
  1134. destroy_content();
  1135. }
  1136. variant()
  1137. {
  1138. // NOTE TO USER :
  1139. // Compile error from here indicates that the first bound
  1140. // type is not default-constructible, and so variant cannot
  1141. // support its own default-construction.
  1142. //
  1143. new( storage_.address() ) internal_T0();
  1144. indicate_which(0); // zero is the index of the first bounded type
  1145. }
  1146. private: // helpers, for structors, cont. (below)
  1147. class convert_copy_into
  1148. : public static_visitor<int>
  1149. {
  1150. private: // representation
  1151. void* storage_;
  1152. public: // structors
  1153. explicit convert_copy_into(void* storage) BOOST_NOEXCEPT
  1154. : storage_(storage)
  1155. {
  1156. }
  1157. public: // internal visitor interfaces (below)
  1158. template <typename T>
  1159. int internal_visit(T& operand, int) const
  1160. {
  1161. // NOTE TO USER :
  1162. // Compile error here indicates one of the source variant's types
  1163. // cannot be unambiguously converted to the destination variant's
  1164. // types (or that no conversion exists).
  1165. //
  1166. return initializer::initialize(storage_, operand);
  1167. }
  1168. # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
  1169. template <typename T>
  1170. result_type internal_visit(const T& operand, int) const
  1171. {
  1172. return initializer::initialize(storage_, operand);
  1173. }
  1174. # endif
  1175. template <typename T>
  1176. int internal_visit(boost::detail::reference_content<T>& operand, long) const
  1177. {
  1178. return internal_visit( operand.get(), 1L );
  1179. }
  1180. template <typename T>
  1181. int internal_visit(const boost::detail::reference_content<T>& operand, long) const
  1182. {
  1183. return internal_visit( operand.get(), 1L );
  1184. }
  1185. template <typename T>
  1186. int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
  1187. {
  1188. return internal_visit( operand.get(), 1L );
  1189. }
  1190. template <typename T>
  1191. int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
  1192. {
  1193. return internal_visit( operand.get(), 1L );
  1194. }
  1195. template <typename T>
  1196. int internal_visit(boost::recursive_wrapper<T>& operand, long) const
  1197. {
  1198. return internal_visit( operand.get(), 1L );
  1199. }
  1200. template <typename T>
  1201. int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
  1202. {
  1203. return internal_visit( operand.get(), 1L );
  1204. }
  1205. };
  1206. friend class convert_copy_into;
  1207. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1208. class convert_move_into
  1209. : public static_visitor<int>
  1210. {
  1211. private: // representation
  1212. void* storage_;
  1213. public: // structors
  1214. explicit convert_move_into(void* storage) BOOST_NOEXCEPT
  1215. : storage_(storage)
  1216. {
  1217. }
  1218. public: // internal visitor interfaces (below)
  1219. template <typename T>
  1220. int internal_visit(T& operand, int) const
  1221. {
  1222. // NOTE TO USER :
  1223. // Compile error here indicates one of the source variant's types
  1224. // cannot be unambiguously converted to the destination variant's
  1225. // types (or that no conversion exists).
  1226. //
  1227. return initializer::initialize(storage_, detail::variant::move(operand) );
  1228. }
  1229. template <typename T>
  1230. int internal_visit(boost::detail::reference_content<T>& operand, long) const
  1231. {
  1232. return internal_visit( operand.get(), 1L );
  1233. }
  1234. template <typename T>
  1235. int internal_visit(const boost::detail::reference_content<T>& operand, long) const
  1236. {
  1237. return internal_visit( operand.get(), 1L );
  1238. }
  1239. template <typename T>
  1240. int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
  1241. {
  1242. return internal_visit( operand.get(), 1L );
  1243. }
  1244. template <typename T>
  1245. int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
  1246. {
  1247. return internal_visit( operand.get(), 1L );
  1248. }
  1249. template <typename T>
  1250. int internal_visit(boost::recursive_wrapper<T>& operand, long) const
  1251. {
  1252. return internal_visit( operand.get(), 1L );
  1253. }
  1254. template <typename T>
  1255. int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
  1256. {
  1257. return internal_visit( operand.get(), 1L );
  1258. }
  1259. };
  1260. friend class convert_move_into;
  1261. #endif
  1262. private: // helpers, for structors, below
  1263. template <typename T>
  1264. void convert_construct(
  1265. T& operand
  1266. , int
  1267. , mpl::false_ = mpl::false_() // is_foreign_variant
  1268. )
  1269. {
  1270. // NOTE TO USER :
  1271. // Compile error here indicates that the given type is not
  1272. // unambiguously convertible to one of the variant's types
  1273. // (or that no conversion exists).
  1274. //
  1275. indicate_which(
  1276. initializer::initialize(
  1277. storage_.address()
  1278. , operand
  1279. )
  1280. );
  1281. }
  1282. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1283. template <typename T>
  1284. typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type convert_construct(
  1285. T&& operand
  1286. , int
  1287. , mpl::false_ = mpl::false_() // is_foreign_variant
  1288. )
  1289. {
  1290. // NOTE TO USER :
  1291. // Compile error here indicates that the given type is not
  1292. // unambiguously convertible to one of the variant's types
  1293. // (or that no conversion exists).
  1294. //
  1295. indicate_which(
  1296. initializer::initialize(
  1297. storage_.address()
  1298. , detail::variant::move(operand)
  1299. )
  1300. );
  1301. }
  1302. #endif
  1303. template <typename Variant>
  1304. void convert_construct(
  1305. Variant& operand
  1306. , long
  1307. , mpl::true_// is_foreign_variant
  1308. )
  1309. {
  1310. convert_copy_into visitor(storage_.address());
  1311. indicate_which(
  1312. operand.internal_apply_visitor(visitor)
  1313. );
  1314. }
  1315. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1316. template <typename Variant>
  1317. typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct(
  1318. Variant&& operand
  1319. , long
  1320. , mpl::true_// is_foreign_variant
  1321. )
  1322. {
  1323. convert_move_into visitor(storage_.address());
  1324. indicate_which(
  1325. operand.internal_apply_visitor(visitor)
  1326. );
  1327. }
  1328. #endif
  1329. template <typename Variant>
  1330. void convert_construct_variant(Variant& operand)
  1331. {
  1332. // [Determine if the given variant is itself a bounded type, or if its
  1333. // content needs to be converted (i.e., it is a 'foreign' variant):]
  1334. //
  1335. typedef typename mpl::find_if<
  1336. types
  1337. , is_same<
  1338. add_const<mpl::_1>
  1339. , const Variant
  1340. >
  1341. >::type found_it;
  1342. typedef typename mpl::end<types>::type not_found;
  1343. typedef typename is_same<
  1344. found_it, not_found
  1345. >::type is_foreign_variant;
  1346. // Convert construct from operand:
  1347. convert_construct(
  1348. operand, 1L
  1349. , is_foreign_variant()
  1350. );
  1351. }
  1352. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1353. template <typename Variant>
  1354. typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct_variant(Variant&& operand)
  1355. {
  1356. // [Determine if the given variant is itself a bounded type, or if its
  1357. // content needs to be converted (i.e., it is a 'foreign' variant):]
  1358. //
  1359. typedef typename mpl::find_if<
  1360. types
  1361. , is_same<
  1362. add_const<mpl::_1>
  1363. , const Variant
  1364. >
  1365. >::type found_it;
  1366. typedef typename mpl::end<types>::type not_found;
  1367. typedef typename is_same<
  1368. found_it, not_found
  1369. >::type is_foreign_variant;
  1370. // Convert move construct from operand:
  1371. convert_construct(
  1372. detail::variant::move(operand), 1L
  1373. , is_foreign_variant()
  1374. );
  1375. }
  1376. #endif
  1377. template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
  1378. void convert_construct(
  1379. boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
  1380. , long
  1381. )
  1382. {
  1383. convert_construct_variant(operand);
  1384. }
  1385. template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
  1386. void convert_construct(
  1387. const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
  1388. , long
  1389. )
  1390. {
  1391. convert_construct_variant(operand);
  1392. }
  1393. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1394. template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
  1395. void convert_construct(
  1396. boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand
  1397. , long
  1398. )
  1399. {
  1400. convert_construct_variant( detail::variant::move(operand) );
  1401. }
  1402. #endif
  1403. public: // structors, cont.
  1404. #if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
  1405. template <typename T>
  1406. variant(const T& operand)
  1407. {
  1408. convert_construct(operand, 1L);
  1409. }
  1410. template <typename T>
  1411. variant(T& operand)
  1412. {
  1413. convert_construct(operand, 1L);
  1414. }
  1415. #elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
  1416. // For compilers that cannot distinguish between T& and const T& in
  1417. // template constructors, but do fully support SFINAE, we can workaround:
  1418. template <typename T>
  1419. variant(const T& operand)
  1420. {
  1421. convert_construct(operand, 1L);
  1422. }
  1423. template <typename T>
  1424. variant(
  1425. T& operand
  1426. , typename enable_if<
  1427. mpl::not_< is_const<T> >
  1428. , void
  1429. >::type* = 0
  1430. )
  1431. {
  1432. convert_construct(operand, 1L);
  1433. }
  1434. #else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
  1435. // For compilers that cannot distinguish between T& and const T& in
  1436. // template constructors, and do NOT support SFINAE, we can't workaround:
  1437. template <typename T>
  1438. variant(const T& operand)
  1439. {
  1440. convert_construct(operand, 1L);
  1441. }
  1442. #endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds
  1443. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1444. template <class T>
  1445. variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0,
  1446. typename boost::disable_if<boost::is_const<T> >::type* = 0)
  1447. {
  1448. convert_construct( detail::variant::move(operand), 1L);
  1449. }
  1450. #endif
  1451. public: // structors, cont.
  1452. // [MSVC6 requires copy constructor appear after template constructors]
  1453. variant(const variant& operand)
  1454. {
  1455. // Copy the value of operand into *this...
  1456. detail::variant::copy_into visitor( storage_.address() );
  1457. operand.internal_apply_visitor(visitor);
  1458. // ...and activate the *this's primary storage on success:
  1459. indicate_which(operand.which());
  1460. }
  1461. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1462. variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept::type::value)
  1463. {
  1464. // Move the value of operand into *this...
  1465. detail::variant::move_into visitor( storage_.address() );
  1466. operand.internal_apply_visitor(visitor);
  1467. // ...and activate the *this's primary storage on success:
  1468. indicate_which(operand.which());
  1469. }
  1470. #endif
  1471. private: // helpers, for modifiers (below)
  1472. # if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  1473. template <typename Variant>
  1474. friend class detail::variant::backup_assigner;
  1475. # endif
  1476. // class assigner
  1477. //
  1478. // Internal visitor that "assigns" the visited value to the given variant
  1479. // by appropriate destruction and copy-construction.
  1480. //
  1481. class assigner
  1482. : public static_visitor<>
  1483. {
  1484. private: // representation
  1485. variant& lhs_;
  1486. int rhs_which_;
  1487. public: // structors
  1488. assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
  1489. : lhs_(lhs)
  1490. , rhs_which_(rhs_which)
  1491. {
  1492. }
  1493. private: // helpers, for internal visitor interface (below)
  1494. template <typename RhsT, typename B1, typename B2>
  1495. void assign_impl(
  1496. const RhsT& rhs_content
  1497. , mpl::true_ // has_nothrow_copy
  1498. , B1 // is_nothrow_move_constructible
  1499. , B2 // has_fallback_type
  1500. )
  1501. {
  1502. // Destroy lhs's content...
  1503. lhs_.destroy_content(); // nothrow
  1504. // ...copy rhs content into lhs's storage...
  1505. new(lhs_.storage_.address())
  1506. RhsT( rhs_content ); // nothrow
  1507. // ...and indicate new content type:
  1508. lhs_.indicate_which(rhs_which_); // nothrow
  1509. }
  1510. template <typename RhsT, typename B>
  1511. void assign_impl(
  1512. const RhsT& rhs_content
  1513. , mpl::false_ // has_nothrow_copy
  1514. , mpl::true_ // is_nothrow_move_constructible
  1515. , B // has_fallback_type
  1516. )
  1517. {
  1518. // Attempt to make a temporary copy (so as to move it below)...
  1519. RhsT temp(rhs_content);
  1520. // ...and upon success destroy lhs's content...
  1521. lhs_.destroy_content(); // nothrow
  1522. // ...move the temporary copy into lhs's storage...
  1523. new(lhs_.storage_.address())
  1524. RhsT( detail::variant::move(temp) ); // nothrow
  1525. // ...and indicate new content type:
  1526. lhs_.indicate_which(rhs_which_); // nothrow
  1527. }
  1528. template <typename RhsT>
  1529. void assign_impl(
  1530. const RhsT& rhs_content
  1531. , mpl::false_ // has_nothrow_copy
  1532. , mpl::false_ // is_nothrow_move_constructible
  1533. , mpl::true_ // has_fallback_type
  1534. )
  1535. {
  1536. // Destroy lhs's content...
  1537. lhs_.destroy_content(); // nothrow
  1538. BOOST_TRY
  1539. {
  1540. // ...and attempt to copy rhs's content into lhs's storage:
  1541. new(lhs_.storage_.address())
  1542. RhsT( rhs_content );
  1543. }
  1544. BOOST_CATCH (...)
  1545. {
  1546. // In case of failure, default-construct fallback type in lhs's storage...
  1547. new (lhs_.storage_.address())
  1548. fallback_type_; // nothrow
  1549. // ...indicate construction of fallback type...
  1550. lhs_.indicate_which(
  1551. BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
  1552. ); // nothrow
  1553. // ...and rethrow:
  1554. BOOST_RETHROW;
  1555. }
  1556. BOOST_CATCH_END
  1557. // In the event of success, indicate new content type:
  1558. lhs_.indicate_which(rhs_which_); // nothrow
  1559. }
  1560. template <typename RhsT>
  1561. void assign_impl(
  1562. const RhsT& rhs_content
  1563. , mpl::false_ // has_nothrow_copy
  1564. , mpl::false_ // is_nothrow_move_constructible
  1565. , mpl::false_ // has_fallback_type
  1566. )
  1567. {
  1568. detail::variant::backup_assigner<wknd_self_t>
  1569. visitor(lhs_, rhs_which_, rhs_content);
  1570. lhs_.internal_apply_visitor(visitor);
  1571. }
  1572. public: // internal visitor interfaces
  1573. template <typename RhsT>
  1574. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  1575. internal_visit(const RhsT& rhs_content, int)
  1576. {
  1577. typedef typename has_nothrow_copy<RhsT>::type
  1578. nothrow_copy;
  1579. typedef typename mpl::or_< // reduces compile-time
  1580. nothrow_copy
  1581. , is_nothrow_move_constructible<RhsT>
  1582. >::type nothrow_move_constructor;
  1583. assign_impl(
  1584. rhs_content
  1585. , nothrow_copy()
  1586. , nothrow_move_constructor()
  1587. , has_fallback_type_()
  1588. );
  1589. BOOST_VARIANT_AUX_RETURN_VOID;
  1590. }
  1591. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  1592. private:
  1593. // silence MSVC warning C4512: assignment operator could not be generated
  1594. assigner& operator= (assigner const&);
  1595. #endif
  1596. };
  1597. friend class assigner;
  1598. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1599. // class move_assigner
  1600. //
  1601. // Internal visitor that "move assigns" the visited value to the given variant
  1602. // by appropriate destruction and move-construction.
  1603. //
  1604. class move_assigner
  1605. : public static_visitor<>
  1606. {
  1607. private: // representation
  1608. variant& lhs_;
  1609. int rhs_which_;
  1610. public: // structors
  1611. move_assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
  1612. : lhs_(lhs)
  1613. , rhs_which_(rhs_which)
  1614. {
  1615. }
  1616. private: // helpers, for internal visitor interface (below)
  1617. template <typename RhsT, typename B2>
  1618. void assign_impl(
  1619. RhsT& rhs_content
  1620. , mpl::true_ // has_nothrow_copy
  1621. , mpl::false_ // is_nothrow_move_constructible
  1622. , B2 // has_fallback_type
  1623. )
  1624. {
  1625. // Destroy lhs's content...
  1626. lhs_.destroy_content(); // nothrow
  1627. // ...copy rhs content into lhs's storage...
  1628. new(lhs_.storage_.address())
  1629. RhsT( rhs_content ); // nothrow
  1630. // ...and indicate new content type:
  1631. lhs_.indicate_which(rhs_which_); // nothrow
  1632. }
  1633. template <typename RhsT, typename B>
  1634. void assign_impl(
  1635. RhsT& rhs_content
  1636. , mpl::true_ // has_nothrow_copy
  1637. , mpl::true_ // is_nothrow_move_constructible
  1638. , B // has_fallback_type
  1639. )
  1640. {
  1641. // ...destroy lhs's content...
  1642. lhs_.destroy_content(); // nothrow
  1643. // ...move the rhs_content into lhs's storage...
  1644. new(lhs_.storage_.address())
  1645. RhsT( detail::variant::move(rhs_content) ); // nothrow
  1646. // ...and indicate new content type:
  1647. lhs_.indicate_which(rhs_which_); // nothrow
  1648. }
  1649. template <typename RhsT>
  1650. void assign_impl(
  1651. RhsT& rhs_content
  1652. , mpl::false_ // has_nothrow_copy
  1653. , mpl::false_ // is_nothrow_move_constructible
  1654. , mpl::true_ // has_fallback_type
  1655. )
  1656. {
  1657. // Destroy lhs's content...
  1658. lhs_.destroy_content(); // nothrow
  1659. BOOST_TRY
  1660. {
  1661. // ...and attempt to copy rhs's content into lhs's storage:
  1662. new(lhs_.storage_.address())
  1663. RhsT( detail::variant::move(rhs_content) );
  1664. }
  1665. BOOST_CATCH (...)
  1666. {
  1667. // In case of failure, default-construct fallback type in lhs's storage...
  1668. new (lhs_.storage_.address())
  1669. fallback_type_; // nothrow
  1670. // ...indicate construction of fallback type...
  1671. lhs_.indicate_which(
  1672. BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
  1673. ); // nothrow
  1674. // ...and rethrow:
  1675. BOOST_RETHROW;
  1676. }
  1677. BOOST_CATCH_END
  1678. // In the event of success, indicate new content type:
  1679. lhs_.indicate_which(rhs_which_); // nothrow
  1680. }
  1681. template <typename RhsT>
  1682. void assign_impl(
  1683. const RhsT& rhs_content
  1684. , mpl::false_ // has_nothrow_copy
  1685. , mpl::false_ // is_nothrow_move_constructible
  1686. , mpl::false_ // has_fallback_type
  1687. )
  1688. {
  1689. detail::variant::backup_assigner<wknd_self_t>
  1690. visitor(lhs_, rhs_which_, rhs_content);
  1691. lhs_.internal_apply_visitor(visitor);
  1692. }
  1693. public: // internal visitor interfaces
  1694. template <typename RhsT>
  1695. BOOST_VARIANT_AUX_RETURN_VOID_TYPE
  1696. internal_visit(RhsT& rhs_content, int)
  1697. {
  1698. typedef typename is_nothrow_move_constructible<RhsT>::type
  1699. nothrow_move_constructor;
  1700. typedef typename mpl::or_< // reduces compile-time
  1701. nothrow_move_constructor
  1702. , has_nothrow_copy<RhsT>
  1703. >::type nothrow_copy;
  1704. assign_impl(
  1705. rhs_content
  1706. , nothrow_copy()
  1707. , nothrow_move_constructor()
  1708. , has_fallback_type_()
  1709. );
  1710. BOOST_VARIANT_AUX_RETURN_VOID;
  1711. }
  1712. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
  1713. private:
  1714. // silence MSVC warning C4512: assignment operator could not be generated
  1715. move_assigner& operator= (move_assigner const&);
  1716. #endif
  1717. };
  1718. friend class move_assigner;
  1719. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  1720. void variant_assign(const variant& rhs)
  1721. {
  1722. // If the contained types are EXACTLY the same...
  1723. if (which_ == rhs.which_)
  1724. {
  1725. // ...then assign rhs's storage to lhs's content:
  1726. detail::variant::assign_storage visitor(rhs.storage_.address());
  1727. this->internal_apply_visitor(visitor);
  1728. }
  1729. else
  1730. {
  1731. // Otherwise, perform general (copy-based) variant assignment:
  1732. assigner visitor(*this, rhs.which());
  1733. rhs.internal_apply_visitor(visitor);
  1734. }
  1735. }
  1736. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1737. void variant_assign(variant&& rhs)
  1738. {
  1739. // If the contained types are EXACTLY the same...
  1740. if (which_ == rhs.which_)
  1741. {
  1742. // ...then move rhs's storage to lhs's content:
  1743. detail::variant::move_storage visitor(rhs.storage_.address());
  1744. this->internal_apply_visitor(visitor);
  1745. }
  1746. else
  1747. {
  1748. // Otherwise, perform general (move-based) variant assignment:
  1749. move_assigner visitor(*this, rhs.which());
  1750. rhs.internal_apply_visitor(visitor);
  1751. }
  1752. }
  1753. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  1754. private: // helpers, for modifiers (below)
  1755. template <typename T>
  1756. void assign(const T& rhs)
  1757. {
  1758. // If direct T-to-T assignment is not possible...
  1759. detail::variant::direct_assigner<T> direct_assign(rhs);
  1760. if (this->apply_visitor(direct_assign) == false)
  1761. {
  1762. // ...then convert rhs to variant and assign:
  1763. //
  1764. // While potentially inefficient, the following construction of a
  1765. // variant allows T as any type convertible to one of the bounded
  1766. // types without excessive code redundancy.
  1767. //
  1768. variant temp(rhs);
  1769. variant_assign( detail::variant::move(temp) );
  1770. }
  1771. }
  1772. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1773. template <typename T>
  1774. void move_assign(T&& rhs)
  1775. {
  1776. // If direct T-to-T move assignment is not possible...
  1777. detail::variant::direct_mover<T> direct_move(rhs);
  1778. if (this->apply_visitor(direct_move) == false)
  1779. {
  1780. // ...then convert rhs to variant and assign:
  1781. //
  1782. // While potentially inefficient, the following construction of a
  1783. // variant allows T as any type convertible to one of the bounded
  1784. // types without excessive code redundancy.
  1785. //
  1786. variant temp( detail::variant::move(rhs) );
  1787. variant_assign( detail::variant::move(temp) );
  1788. }
  1789. }
  1790. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  1791. public: // modifiers
  1792. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1793. template <class T>
  1794. typename boost::enable_if_c<boost::is_rvalue_reference<T&&>::value && !boost::is_const<T>::value, variant& >::type
  1795. operator=(T&& rhs)
  1796. {
  1797. move_assign( detail::variant::move(rhs) );
  1798. return *this;
  1799. }
  1800. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  1801. template <typename T>
  1802. variant& operator=(const T& rhs)
  1803. {
  1804. assign(rhs);
  1805. return *this;
  1806. }
  1807. // [MSVC6 requires copy assign appear after templated operator=]
  1808. variant& operator=(const variant& rhs)
  1809. {
  1810. variant_assign(rhs);
  1811. return *this;
  1812. }
  1813. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1814. variant& operator=(variant&& rhs) // BOOST_NOEXCEPT_IF(variant_move_noexcept::type::value && all move assign operators are noexcept)
  1815. {
  1816. variant_assign( detail::variant::move(rhs) );
  1817. return *this;
  1818. }
  1819. #endif // BOOST_NO_CXX11_RVALUE_REFERENCES
  1820. void swap(variant& rhs)
  1821. {
  1822. // If the contained types are the same...
  1823. if (which() == rhs.which())
  1824. {
  1825. // ...then swap the values directly:
  1826. detail::variant::swap_with<variant> visitor(rhs);
  1827. this->apply_visitor(visitor);
  1828. }
  1829. else
  1830. {
  1831. // ...otherwise, perform general variant swap:
  1832. variant tmp( detail::variant::move(rhs) );
  1833. rhs = detail::variant::move(*this);
  1834. *this = detail::variant::move(tmp);
  1835. }
  1836. }
  1837. public: // queries
  1838. //
  1839. // NOTE: member which() defined above.
  1840. //
  1841. bool empty() const BOOST_NOEXCEPT
  1842. {
  1843. return false;
  1844. }
  1845. #if !defined(BOOST_NO_TYPEID)
  1846. const std::type_info& type() const
  1847. {
  1848. detail::variant::reflect visitor;
  1849. return this->apply_visitor(visitor);
  1850. }
  1851. #endif
  1852. public: // prevent comparison with foreign types
  1853. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  1854. # define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
  1855. void
  1856. #else // MSVC7
  1857. //
  1858. // MSVC7 gives error about return types for above being different than
  1859. // the true comparison operator overloads:
  1860. //
  1861. # define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
  1862. bool
  1863. #endif // MSVC7 workaround
  1864. template <typename U>
  1865. BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
  1866. operator==(const U&) const
  1867. {
  1868. BOOST_STATIC_ASSERT( false && sizeof(U) );
  1869. }
  1870. template <typename U>
  1871. BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE
  1872. operator<(const U&) const
  1873. {
  1874. BOOST_STATIC_ASSERT( false && sizeof(U) );
  1875. }
  1876. public: // comparison operators
  1877. // [MSVC6 requires these operators appear after template operators]
  1878. bool operator==(const variant& rhs) const
  1879. {
  1880. if (this->which() != rhs.which())
  1881. return false;
  1882. detail::variant::comparer<
  1883. variant, detail::variant::equal_comp
  1884. > visitor(*this);
  1885. return rhs.apply_visitor(visitor);
  1886. }
  1887. bool operator<(const variant& rhs) const
  1888. {
  1889. //
  1890. // Dirk Schreib suggested this collating order.
  1891. //
  1892. if (this->which() != rhs.which())
  1893. return this->which() < rhs.which();
  1894. detail::variant::comparer<
  1895. variant, detail::variant::less_comp
  1896. > visitor(*this);
  1897. return rhs.apply_visitor(visitor);
  1898. }
  1899. // helpers, for visitation support (below) -- private when possible
  1900. #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  1901. template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
  1902. friend class variant;
  1903. private:
  1904. #else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  1905. public:
  1906. #endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
  1907. template <typename Visitor, typename VoidPtrCV>
  1908. static
  1909. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  1910. typename Visitor::result_type
  1911. )
  1912. internal_apply_visitor_impl(
  1913. int internal_which
  1914. , int logical_which
  1915. , Visitor& visitor
  1916. , VoidPtrCV storage
  1917. )
  1918. {
  1919. typedef mpl::int_<0> first_which;
  1920. typedef typename mpl::begin<internal_types>::type first_it;
  1921. typedef typename mpl::end<internal_types>::type last_it;
  1922. typedef detail::variant::visitation_impl_step<
  1923. first_it, last_it
  1924. > first_step;
  1925. return detail::variant::visitation_impl(
  1926. internal_which, logical_which
  1927. , visitor, storage, mpl::false_()
  1928. , never_uses_backup_flag()
  1929. , static_cast<first_which*>(0), static_cast<first_step*>(0)
  1930. );
  1931. }
  1932. template <typename Visitor>
  1933. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  1934. typename Visitor::result_type
  1935. )
  1936. internal_apply_visitor(Visitor& visitor)
  1937. {
  1938. return internal_apply_visitor_impl(
  1939. which_, which(), visitor, storage_.address()
  1940. );
  1941. }
  1942. template <typename Visitor>
  1943. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  1944. typename Visitor::result_type
  1945. )
  1946. internal_apply_visitor(Visitor& visitor) const
  1947. {
  1948. return internal_apply_visitor_impl(
  1949. which_, which(), visitor, storage_.address()
  1950. );
  1951. }
  1952. public: // visitation support
  1953. template <typename Visitor>
  1954. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  1955. typename Visitor::result_type
  1956. )
  1957. apply_visitor(Visitor& visitor)
  1958. {
  1959. detail::variant::invoke_visitor<Visitor> invoker(visitor);
  1960. return this->internal_apply_visitor(invoker);
  1961. }
  1962. template <typename Visitor>
  1963. BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
  1964. typename Visitor::result_type
  1965. )
  1966. apply_visitor(Visitor& visitor) const
  1967. {
  1968. detail::variant::invoke_visitor<Visitor> invoker(visitor);
  1969. return this->internal_apply_visitor(invoker);
  1970. }
  1971. }; // class variant
  1972. ///////////////////////////////////////////////////////////////////////////////
  1973. // metafunction make_variant_over
  1974. //
  1975. // See docs and boost/variant/variant_fwd.hpp for more information.
  1976. //
  1977. template <typename Types>
  1978. struct make_variant_over
  1979. {
  1980. private: // precondition assertions
  1981. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  1982. BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
  1983. #endif
  1984. public: // metafunction result
  1985. typedef variant<
  1986. detail::variant::over_sequence< Types >
  1987. > type;
  1988. };
  1989. ///////////////////////////////////////////////////////////////////////////////
  1990. // function template swap
  1991. //
  1992. // Swaps two variants of the same type (i.e., identical specification).
  1993. //
  1994. template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
  1995. inline void swap(
  1996. variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs
  1997. , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs
  1998. )
  1999. {
  2000. lhs.swap(rhs);
  2001. }
  2002. } // namespace boost
  2003. // implementation additions
  2004. #if !defined(BOOST_NO_IOSTREAM)
  2005. #include "boost/variant/detail/variant_io.hpp"
  2006. #endif // BOOST_NO_IOSTREAM
  2007. #endif // BOOST_VARIANT_VARIANT_HPP