microsoft.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. #ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP
  2. #define BOOST_RANGE_DETAIL_MICROSOFT_HPP
  3. // Boost.Range MFC/ATL Extension
  4. //
  5. // Copyright Shunsuke Sogame 2005-2006.
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. // config
  10. //
  11. #include <boost/range/iterator.hpp>
  12. #define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1
  13. #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
  14. #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
  15. #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin
  16. #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end
  17. #else
  18. #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator
  19. #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin
  20. #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end
  21. #endif
  22. // yet another customization way
  23. //
  24. #include <boost/iterator/iterator_traits.hpp> // iterator_difference
  25. #include <boost/mpl/identity.hpp>
  26. #include <boost/mpl/if.hpp>
  27. #include <boost/preprocessor/cat.hpp>
  28. #include <boost/preprocessor/control/iif.hpp>
  29. #include <boost/preprocessor/comma_if.hpp>
  30. #include <boost/preprocessor/detail/is_unary.hpp>
  31. #include <boost/preprocessor/list/for_each.hpp>
  32. #include <boost/preprocessor/repetition/enum_params.hpp>
  33. #include <boost/preprocessor/repetition/repeat.hpp>
  34. #include <boost/preprocessor/seq/for_each_i.hpp>
  35. #include <boost/preprocessor/seq/size.hpp>
  36. #include <boost/preprocessor/tuple/eat.hpp>
  37. #include <boost/range/const_iterator.hpp>
  38. #include <boost/range/size_type.hpp>
  39. #include <boost/type_traits/is_const.hpp>
  40. #include <boost/type_traits/is_same.hpp>
  41. #include <boost/type_traits/remove_cv.hpp>
  42. #include <boost/utility/addressof.hpp>
  43. #include <boost/utility/enable_if.hpp> // disable_if
  44. #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
  45. #include <boost/range/mutable_iterator.hpp>
  46. #else
  47. #include <iterator> // distance
  48. #include <boost/range/begin.hpp>
  49. #include <boost/range/end.hpp>
  50. #include <boost/range/iterator.hpp>
  51. #endif
  52. namespace boost { namespace range_detail_microsoft {
  53. // customization point
  54. //
  55. template< class Tag >
  56. struct customization;
  57. template< class T >
  58. struct customization_tag;
  59. struct using_type_as_tag
  60. { };
  61. // Topic:
  62. // In fact, it is unnecessary for VC++.
  63. // VC++'s behavior seems conforming, while GCC fails without this.
  64. template< class Iterator, class T >
  65. struct mutable_ :
  66. disable_if< is_const<T>, Iterator >
  67. { };
  68. // helpers
  69. //
  70. template< class Tag, class T >
  71. struct customization_tag_of
  72. {
  73. typedef typename mpl::if_< is_same<using_type_as_tag, Tag>,
  74. T,
  75. Tag
  76. >::type type;
  77. };
  78. template< class T >
  79. struct customization_of
  80. {
  81. typedef typename remove_cv<T>::type bare_t;
  82. typedef typename customization_tag<bare_t>::type tag_t;
  83. typedef customization<tag_t> type;
  84. };
  85. template< class T >
  86. struct mutable_iterator_of
  87. {
  88. typedef typename remove_cv<T>::type bare_t;
  89. typedef typename customization_of<bare_t>::type cust_t;
  90. typedef typename cust_t::template meta<bare_t>::mutable_iterator type;
  91. };
  92. template< class T >
  93. struct const_iterator_of
  94. {
  95. typedef typename remove_cv<T>::type bare_t;
  96. typedef typename customization_of<bare_t>::type cust_t;
  97. typedef typename cust_t::template meta<bare_t>::const_iterator type;
  98. };
  99. template< class T >
  100. struct size_type_of
  101. {
  102. typedef typename range_detail_microsoft::mutable_iterator_of<T>::type miter_t;
  103. typedef typename iterator_difference<miter_t>::type type;
  104. };
  105. template< class T > inline
  106. typename mutable_iterator_of<T>::type
  107. begin_of(T& x)
  108. {
  109. typedef typename customization_of<T>::type cust_t;
  110. return cust_t().template begin<typename mutable_iterator_of<T>::type>(x);
  111. }
  112. template< class T > inline
  113. typename const_iterator_of<T>::type
  114. begin_of(T const& x)
  115. {
  116. typedef typename customization_of<T>::type cust_t;
  117. return cust_t().template begin<typename const_iterator_of<T>::type>(x);
  118. }
  119. template< class T > inline
  120. typename mutable_iterator_of<T>::type
  121. end_of(T& x)
  122. {
  123. typedef typename customization_of<T>::type cust_t;
  124. return cust_t().template end<typename mutable_iterator_of<T>::type>(x);
  125. }
  126. template< class T > inline
  127. typename const_iterator_of<T>::type
  128. end_of(T const& x)
  129. {
  130. typedef typename customization_of<T>::type cust_t;
  131. return cust_t().template end<typename const_iterator_of<T>::type>(x);
  132. }
  133. #if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
  134. template< class T > inline
  135. typename size_type_of<T>::type
  136. size_of(T const& x)
  137. {
  138. return std::distance(boost::begin(x), boost::end(x));
  139. }
  140. #endif
  141. template< class Range >
  142. struct compatible_mutable_iterator :
  143. BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>
  144. { };
  145. } } // namespace boost::range_detail_microsoft
  146. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
  147. BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \
  148. /**/
  149. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \
  150. namespace elem { \
  151. /**/
  152. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
  153. BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \
  154. /**/
  155. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \
  156. } \
  157. /**/
  158. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \
  159. :: elem \
  160. /**/
  161. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \
  162. namespace boost { namespace range_detail_microsoft { \
  163. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  164. } } \
  165. \
  166. namespace boost { \
  167. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  168. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  169. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  170. } \
  171. \
  172. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
  173. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  174. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  175. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  176. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  177. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \
  178. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
  179. /**/
  180. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \
  181. BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \
  182. /**/
  183. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \
  184. template< > \
  185. struct customization_tag< Fullname > : \
  186. customization_tag_of< Tag, Fullname > \
  187. { }; \
  188. /**/
  189. // metafunctions
  190. //
  191. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \
  192. template< > \
  193. struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
  194. range_detail_microsoft::mutable_iterator_of< Fullname > \
  195. { }; \
  196. /**/
  197. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \
  198. template< > \
  199. struct range_const_iterator< Fullname > : \
  200. range_detail_microsoft::const_iterator_of< Fullname > \
  201. { }; \
  202. /**/
  203. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \
  204. template< > \
  205. struct range_size< Fullname > : \
  206. range_detail_microsoft::size_type_of< Fullname > \
  207. { }; \
  208. /**/
  209. // functions
  210. //
  211. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \
  212. inline \
  213. boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
  214. BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
  215. { \
  216. return boost::range_detail_microsoft::begin_of(x); \
  217. } \
  218. /**/
  219. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \
  220. inline \
  221. boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
  222. BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
  223. { \
  224. return boost::range_detail_microsoft::begin_of(x); \
  225. } \
  226. /**/
  227. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \
  228. inline \
  229. boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
  230. BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
  231. { \
  232. return boost::range_detail_microsoft::end_of(x); \
  233. } \
  234. /**/
  235. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \
  236. inline \
  237. boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
  238. BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
  239. { \
  240. return boost::range_detail_microsoft::end_of(x); \
  241. } \
  242. /**/
  243. #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
  244. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
  245. /**/
  246. #else
  247. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \
  248. inline \
  249. boost::range_detail_microsoft::size_type_of< Fullname >::type \
  250. boost_range_size(Fullname const& x) \
  251. { \
  252. return boost::range_detail_microsoft::size_of(x); \
  253. } \
  254. /**/
  255. #endif
  256. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \
  257. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \
  258. Tag, NamespaceList, Name, \
  259. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
  260. ) \
  261. /**/
  262. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \
  263. BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \
  264. ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \
  265. BOOST_PP_REPEAT \
  266. )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \
  267. /**/
  268. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \
  269. (class) \
  270. /**/
  271. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \
  272. namespace boost { namespace range_detail_microsoft { \
  273. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \
  274. Tag, \
  275. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  276. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  277. ) \
  278. } } \
  279. \
  280. namespace boost { \
  281. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \
  282. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  283. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  284. ) \
  285. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \
  286. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  287. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  288. ) \
  289. \
  290. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \
  291. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  292. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  293. ) \
  294. } \
  295. \
  296. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \
  297. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \
  298. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  299. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  300. ) \
  301. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \
  302. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  303. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  304. ) \
  305. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \
  306. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  307. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  308. ) \
  309. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \
  310. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  311. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  312. ) \
  313. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \
  314. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \
  315. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  316. ) \
  317. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \
  318. /**/
  319. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \
  320. BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \
  321. /**/
  322. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \
  323. BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \
  324. /**/
  325. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \
  326. BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \
  327. :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \
  328. /**/
  329. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \
  330. template< Params > \
  331. struct customization_tag< Fullname > : \
  332. customization_tag_of< Tag, Fullname > \
  333. { }; \
  334. /**/
  335. // metafunctions
  336. //
  337. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \
  338. template< Params > \
  339. struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \
  340. range_detail_microsoft::mutable_iterator_of< Fullname > \
  341. { }; \
  342. /**/
  343. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \
  344. template< Params > \
  345. struct range_const_iterator< Fullname > : \
  346. range_detail_microsoft::const_iterator_of< Fullname > \
  347. { }; \
  348. /**/
  349. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \
  350. template< Params > \
  351. struct range_size< Fullname > : \
  352. range_detail_microsoft::size_type_of< Fullname > \
  353. { }; \
  354. /**/
  355. // functions
  356. //
  357. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \
  358. template< Params > inline \
  359. typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
  360. BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \
  361. { \
  362. return boost::range_detail_microsoft::begin_of(x); \
  363. } \
  364. /**/
  365. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \
  366. template< Params > inline \
  367. typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
  368. BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \
  369. { \
  370. return boost::range_detail_microsoft::begin_of(x); \
  371. } \
  372. /**/
  373. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \
  374. template< Params > inline \
  375. typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \
  376. BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \
  377. { \
  378. return boost::range_detail_microsoft::end_of(x); \
  379. } \
  380. /**/
  381. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \
  382. template< Params > inline \
  383. typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \
  384. BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \
  385. { \
  386. return boost::range_detail_microsoft::end_of(x); \
  387. } \
  388. /**/
  389. #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1)
  390. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
  391. /**/
  392. #else
  393. #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \
  394. template< Params > inline \
  395. typename boost::range_detail_microsoft::size_type_of< Fullname >::type \
  396. boost_range_size(Fullname const& x) \
  397. { \
  398. return boost::range_detail_microsoft::size_of(x); \
  399. } \
  400. /**/
  401. #endif
  402. // list_iterator and helpers
  403. //
  404. #include <boost/assert.hpp>
  405. #include <boost/iterator/iterator_categories.hpp>
  406. #include <boost/iterator/iterator_facade.hpp>
  407. #include <boost/mpl/if.hpp>
  408. #include <boost/type_traits/is_same.hpp>
  409. // POSITION's header is undocumented, so is NULL.
  410. //
  411. struct __POSITION; // incomplete, but used as just a pointer.
  412. typedef __POSITION *POSITION;
  413. namespace boost { namespace range_detail_microsoft {
  414. template<
  415. class ListT,
  416. class Value,
  417. class Reference,
  418. class Traversal
  419. >
  420. struct list_iterator;
  421. template<
  422. class ListT,
  423. class Value,
  424. class Reference,
  425. class Traversal
  426. >
  427. struct list_iterator_super
  428. {
  429. typedef typename mpl::if_< is_same<use_default, Reference>,
  430. Value&,
  431. Reference
  432. >::type ref_t;
  433. typedef typename mpl::if_< is_same<use_default, Traversal>,
  434. bidirectional_traversal_tag,
  435. Traversal
  436. >::type trv_t;
  437. typedef iterator_facade<
  438. list_iterator<ListT, Value, Reference, Traversal>,
  439. Value,
  440. trv_t,
  441. ref_t
  442. > type;
  443. };
  444. template<
  445. class ListT,
  446. class Value,
  447. class Reference = use_default,
  448. class Traversal = use_default
  449. >
  450. struct list_iterator :
  451. list_iterator_super<ListT, Value, Reference, Traversal>::type
  452. {
  453. private:
  454. typedef list_iterator self_t;
  455. typedef typename list_iterator_super<ListT, Value, Reference, Traversal>::type super_t;
  456. typedef typename super_t::reference ref_t;
  457. public:
  458. explicit list_iterator()
  459. { }
  460. explicit list_iterator(ListT& lst, POSITION pos) :
  461. m_plst(boost::addressof(lst)), m_pos(pos)
  462. { }
  463. template< class, class, class, class > friend struct list_iterator;
  464. template< class ListT_, class Value_, class Reference_, class Traversal_>
  465. list_iterator(list_iterator<ListT_, Value_, Reference_, Traversal_> const& other) :
  466. m_plst(other.m_plst), m_pos(other.m_pos)
  467. { }
  468. private:
  469. ListT *m_plst;
  470. POSITION m_pos;
  471. friend class iterator_core_access;
  472. ref_t dereference() const
  473. {
  474. BOOST_ASSERT(m_pos != 0 && "out of range");
  475. return m_plst->GetAt(m_pos);
  476. }
  477. // A B C D x
  478. // Head Tail NULL(0)
  479. //
  480. void increment()
  481. {
  482. BOOST_ASSERT(m_pos != 0 && "out of range");
  483. m_plst->GetNext(m_pos);
  484. }
  485. void decrement()
  486. {
  487. if (m_pos == 0) {
  488. m_pos = m_plst->GetTailPosition();
  489. return;
  490. }
  491. m_plst->GetPrev(m_pos);
  492. }
  493. bool equal(self_t const& other) const
  494. {
  495. BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible");
  496. return m_pos == other.m_pos;
  497. }
  498. };
  499. // customization helpers
  500. //
  501. struct array_functions
  502. {
  503. template< class Iterator, class X >
  504. Iterator begin(X& x)
  505. {
  506. return x.GetData();
  507. }
  508. template< class Iterator, class X >
  509. Iterator end(X& x)
  510. {
  511. return begin<Iterator>(x) + x.GetSize();
  512. }
  513. };
  514. struct list_functions
  515. {
  516. template< class Iterator, class X >
  517. Iterator begin(X& x)
  518. {
  519. return Iterator(x, x.GetHeadPosition());
  520. }
  521. template< class Iterator, class X >
  522. Iterator end(X& x)
  523. {
  524. return Iterator(x, POSITION(0));
  525. }
  526. };
  527. } } // namespace boost::range_detail_microsoft
  528. // test
  529. //
  530. #if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
  531. #include <algorithm>
  532. #include <iterator>
  533. #include <vector>
  534. #include <boost/concept_check.hpp>
  535. #include <boost/next_prior.hpp>
  536. #include <boost/range/begin.hpp>
  537. #include <boost/range/concepts.hpp>
  538. #include <boost/range/const_iterator.hpp>
  539. #include <boost/range/difference_type.hpp>
  540. #include <boost/range/distance.hpp>
  541. #include <boost/range/empty.hpp>
  542. #include <boost/range/iterator_range.hpp>
  543. #include <boost/range/mutable_iterator.hpp>
  544. #include <boost/range/rbegin.hpp>
  545. #include <boost/range/rend.hpp>
  546. #include <boost/range/value_type.hpp>
  547. #include <boost/type_traits/is_same.hpp>
  548. namespace boost { namespace range_detail_microsoft {
  549. template< class Range1, class Range2 >
  550. bool test_equals(Range1 const& rng1, Range2 const& rng2)
  551. {
  552. return
  553. boost::distance(rng1) == boost::distance(rng2) &&
  554. std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2))
  555. ;
  556. }
  557. template< class AssocContainer, class PairT >
  558. bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa)
  559. {
  560. typedef typename boost::range_const_iterator<AssocContainer>::type iter_t;
  561. for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) {
  562. if (it->first == pa.first && it->second == pa.second)
  563. return true;
  564. }
  565. return false;
  566. }
  567. // test functions
  568. //
  569. template< class Range >
  570. bool test_emptiness(Range& )
  571. {
  572. bool result = true;
  573. Range emptyRng;
  574. result = result && boost::empty(emptyRng);
  575. return result;
  576. }
  577. template< class Range >
  578. bool test_trivial(Range& rng)
  579. {
  580. bool result = true;
  581. // convertibility check
  582. typedef typename range_const_iterator<Range>::type citer_t;
  583. citer_t cit = boost::begin(rng);
  584. (void)cit; // unused
  585. // mutability check
  586. typedef typename range_value<Range>::type val_t;
  587. val_t v = *boost::begin(rng);
  588. *boost::begin(rng) = v;
  589. result = result && *boost::begin(rng) == v;
  590. return result;
  591. }
  592. template< class Range >
  593. bool test_forward(Range& rng)
  594. {
  595. boost::function_requires< ForwardRangeConcept<Range> >();
  596. bool result = (test_trivial)(rng);
  597. typedef typename range_value<Range>::type val_t;
  598. std::vector<val_t> saved;
  599. std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
  600. std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved));
  601. std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng));
  602. return result && (test_equals)(saved, rng);
  603. };
  604. template< class Range >
  605. bool test_bidirectional(Range& rng)
  606. {
  607. boost::function_requires< BidirectionalRangeConcept<Range> >();
  608. bool result = (test_forward)(rng);
  609. typedef typename range_value<Range>::type val_t;
  610. std::vector<val_t> saved;
  611. std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
  612. result = result && (test_equals)(
  613. boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)),
  614. boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng))
  615. );
  616. return result;
  617. }
  618. template< class Range >
  619. bool test_random_access(Range& rng)
  620. {
  621. boost::function_requires< RandomAccessRangeConcept<Range> >();
  622. bool result = (test_bidirectional)(rng);
  623. typedef typename range_value<Range>::type val_t;
  624. std::vector<val_t> saved;
  625. std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved));
  626. std::sort(boost::begin(saved), boost::end(saved));
  627. std::random_shuffle(boost::begin(rng), boost::end(rng));
  628. std::sort(boost::begin(rng), boost::end(rng));
  629. result = result && (test_equals)(rng, saved);
  630. std::random_shuffle(boost::begin(rng), boost::end(rng));
  631. std::stable_sort(boost::begin(rng), boost::end(rng));
  632. result = result && (test_equals)(rng, saved);
  633. std::random_shuffle(boost::begin(rng), boost::end(rng));
  634. std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng));
  635. result = result && (test_equals)(rng, saved);
  636. return result;
  637. }
  638. // initializer
  639. //
  640. template< class ArrayT, class SampleRange >
  641. bool test_init_array(ArrayT& arr, SampleRange const& sample)
  642. {
  643. typedef typename range_const_iterator<SampleRange>::type iter_t;
  644. typedef typename range_value<SampleRange>::type val_t;
  645. for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
  646. val_t v = *it; // works around ATL3 CSimpleArray
  647. arr.Add(v);
  648. }
  649. return (test_equals)(arr, sample);
  650. }
  651. template< class ListT, class SampleRange >
  652. bool test_init_list(ListT& lst, SampleRange const& sample)
  653. {
  654. typedef typename range_const_iterator<SampleRange>::type iter_t;
  655. for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
  656. lst.AddTail(*it);
  657. }
  658. return (test_equals)(lst, sample);
  659. }
  660. template< class StringT, class SampleRange >
  661. bool test_init_string(StringT& str, SampleRange const& sample)
  662. {
  663. typedef typename range_const_iterator<SampleRange>::type iter_t;
  664. typedef typename range_value<SampleRange>::type val_t;
  665. for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
  666. str += *it;
  667. }
  668. return (test_equals)(str, sample);
  669. }
  670. template< class MapT, class SampleMap >
  671. bool test_init_map(MapT& map, SampleMap const& sample)
  672. {
  673. typedef typename range_const_iterator<SampleMap>::type iter_t;
  674. for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
  675. map.SetAt(it->first, it->second);
  676. }
  677. return boost::distance(map) == boost::distance(sample);
  678. }
  679. // metafunction test
  680. //
  681. template< class Range, class Iter >
  682. struct test_mutable_iter :
  683. boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator<Range>::type, Iter >
  684. { };
  685. template< class Range, class Iter >
  686. struct test_const_iter :
  687. boost::is_same< typename boost::range_const_iterator<Range>::type, Iter >
  688. { };
  689. } } // namespace boost::range_detail_microsoft
  690. #endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST)
  691. #endif