microsoft.hpp 28 KB

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