mfc.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. #ifndef BOOST_RANGE_MFC_HPP
  2. #define BOOST_RANGE_MFC_HPP
  3. // Boost.Range MFC 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 <afx.h> // _MFC_VER
  12. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  13. #if (_MFC_VER < 0x0700) // dubious
  14. #define BOOST_RANGE_MFC_NO_CPAIR
  15. #endif
  16. #endif
  17. #if !defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  18. #if (_MFC_VER < 0x0700) // dubious
  19. #define BOOST_RANGE_MFC_HAS_LEGACY_STRING
  20. #endif
  21. #endif
  22. // A const collection of old MFC doesn't return const reference.
  23. //
  24. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  25. #if (_MFC_VER < 0x0700) // dubious
  26. #define BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF
  27. #endif
  28. #endif
  29. // forward declarations
  30. //
  31. template< class Type, class ArgType >
  32. class CArray;
  33. template< class Type, class ArgType >
  34. class CList;
  35. template< class Key, class ArgKey, class Mapped, class ArgMapped >
  36. class CMap;
  37. template< class BaseClass, class PtrType >
  38. class CTypedPtrArray;
  39. template< class BaseClass, class PtrType >
  40. class CTypedPtrList;
  41. template< class BaseClass, class KeyPtrType, class MappedPtrType >
  42. class CTypedPtrMap;
  43. // extended customizations
  44. //
  45. #include <cstddef> // ptrdiff_t
  46. #include <utility> // pair
  47. #include <boost/assert.hpp>
  48. #include <boost/mpl/if.hpp>
  49. #include <boost/range/atl.hpp>
  50. #include <boost/range/begin.hpp>
  51. #include <boost/range/const_iterator.hpp>
  52. #include <boost/range/detail/microsoft.hpp>
  53. #include <boost/range/end.hpp>
  54. #include <boost/iterator/iterator_adaptor.hpp>
  55. #include <boost/iterator/iterator_categories.hpp>
  56. #include <boost/iterator/iterator_facade.hpp>
  57. #include <boost/iterator/transform_iterator.hpp>
  58. #include <boost/type_traits/is_const.hpp>
  59. #include <boost/type_traits/remove_pointer.hpp>
  60. #include <boost/utility/addressof.hpp>
  61. #include <afx.h> // legacy CString
  62. #include <afxcoll.h> // CXXXArray, CXXXList, CMapXXXToXXX
  63. #include <tchar.h>
  64. namespace boost { namespace range_detail_microsoft {
  65. // mfc_ptr_array_iterator
  66. //
  67. // 'void **' is not convertible to 'void const **',
  68. // so we define...
  69. //
  70. template< class ArrayT, class PtrType >
  71. struct mfc_ptr_array_iterator;
  72. template< class ArrayT, class PtrType >
  73. struct mfc_ptr_array_iterator_super
  74. {
  75. typedef iterator_adaptor<
  76. mfc_ptr_array_iterator<ArrayT, PtrType>,
  77. std::ptrdiff_t, // Base!
  78. PtrType, // Value
  79. random_access_traversal_tag,
  80. use_default,
  81. std::ptrdiff_t // Difference
  82. > type;
  83. };
  84. template< class ArrayT, class PtrType >
  85. struct mfc_ptr_array_iterator :
  86. mfc_ptr_array_iterator_super<ArrayT, PtrType>::type
  87. {
  88. private:
  89. typedef mfc_ptr_array_iterator self_t;
  90. typedef typename mfc_ptr_array_iterator_super<ArrayT, PtrType>::type super_t;
  91. typedef typename super_t::reference ref_t;
  92. public:
  93. explicit mfc_ptr_array_iterator()
  94. { }
  95. explicit mfc_ptr_array_iterator(ArrayT& arr, INT_PTR index) :
  96. super_t(index), m_parr(boost::addressof(arr))
  97. { }
  98. template< class, class > friend struct mfc_ptr_array_iterator;
  99. template< class ArrayT_, class PtrType_ >
  100. mfc_ptr_array_iterator(mfc_ptr_array_iterator<ArrayT_, PtrType_> const& other) :
  101. super_t(other.base()), m_parr(other.m_parr)
  102. { }
  103. private:
  104. ArrayT *m_parr;
  105. friend class iterator_core_access;
  106. ref_t dereference() const
  107. {
  108. BOOST_ASSERT(0 <= this->base() && this->base() < m_parr->GetSize() && "out of range");
  109. return *( m_parr->GetData() + this->base() );
  110. }
  111. bool equal(self_t const& other) const
  112. {
  113. BOOST_ASSERT(m_parr == other.m_parr && "iterators incompatible");
  114. return this->base() == other.base();
  115. }
  116. };
  117. struct mfc_ptr_array_functions
  118. {
  119. template< class Iterator, class X >
  120. Iterator begin(X& x)
  121. {
  122. return Iterator(x, 0);
  123. }
  124. template< class Iterator, class X >
  125. Iterator end(X& x)
  126. {
  127. return Iterator(x, x.GetSize());
  128. }
  129. };
  130. // arrays
  131. //
  132. template< >
  133. struct customization< ::CByteArray > :
  134. array_functions
  135. {
  136. template< class X >
  137. struct meta
  138. {
  139. typedef BYTE val_t;
  140. typedef val_t *mutable_iterator;
  141. typedef val_t const *const_iterator;
  142. };
  143. };
  144. template< >
  145. struct customization< ::CDWordArray > :
  146. array_functions
  147. {
  148. template< class X >
  149. struct meta
  150. {
  151. typedef DWORD val_t;
  152. typedef val_t *mutable_iterator;
  153. typedef val_t const *const_iterator;
  154. };
  155. };
  156. template< >
  157. struct customization< ::CObArray > :
  158. mfc_ptr_array_functions
  159. {
  160. template< class X >
  161. struct meta
  162. {
  163. typedef mfc_ptr_array_iterator<X, CObject *> mutable_iterator;
  164. typedef mfc_ptr_array_iterator<X const, CObject const *> const_iterator;
  165. };
  166. };
  167. template< >
  168. struct customization< ::CPtrArray > :
  169. mfc_ptr_array_functions
  170. {
  171. template< class X >
  172. struct meta
  173. {
  174. typedef mfc_ptr_array_iterator<X, void *> mutable_iterator;
  175. typedef mfc_ptr_array_iterator<X const, void const *> const_iterator;
  176. };
  177. };
  178. template< >
  179. struct customization< ::CStringArray > :
  180. array_functions
  181. {
  182. template< class X >
  183. struct meta
  184. {
  185. typedef ::CString val_t;
  186. typedef val_t *mutable_iterator;
  187. typedef val_t const *const_iterator;
  188. };
  189. };
  190. template< >
  191. struct customization< ::CUIntArray > :
  192. array_functions
  193. {
  194. template< class X >
  195. struct meta
  196. {
  197. typedef UINT val_t;
  198. typedef val_t *mutable_iterator;
  199. typedef val_t const *const_iterator;
  200. };
  201. };
  202. template< >
  203. struct customization< ::CWordArray > :
  204. array_functions
  205. {
  206. template< class X >
  207. struct meta
  208. {
  209. typedef WORD val_t;
  210. typedef val_t *mutable_iterator;
  211. typedef val_t const *const_iterator;
  212. };
  213. };
  214. // lists
  215. //
  216. template< >
  217. struct customization< ::CObList > :
  218. list_functions
  219. {
  220. template< class X >
  221. struct meta
  222. {
  223. typedef list_iterator<X, ::CObject *> mutable_iterator;
  224. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  225. typedef list_iterator<X const, ::CObject const *> const_iterator;
  226. #else
  227. typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
  228. #endif
  229. };
  230. };
  231. template< >
  232. struct customization< ::CPtrList > :
  233. list_functions
  234. {
  235. template< class X >
  236. struct meta
  237. {
  238. typedef list_iterator<X, void *> mutable_iterator;
  239. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  240. typedef list_iterator<X const, void const *> const_iterator;
  241. #else
  242. typedef list_iterator<X const, void const * const, void const * const> const_iterator;
  243. #endif
  244. };
  245. };
  246. template< >
  247. struct customization< ::CStringList > :
  248. list_functions
  249. {
  250. template< class X >
  251. struct meta
  252. {
  253. typedef ::CString val_t;
  254. typedef list_iterator<X, val_t> mutable_iterator;
  255. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  256. typedef list_iterator<X const, val_t const> const_iterator;
  257. #else
  258. typedef list_iterator<X const, val_t const, val_t const> const_iterator;
  259. #endif
  260. };
  261. };
  262. // mfc_map_iterator
  263. //
  264. template< class MapT, class KeyT, class MappedT >
  265. struct mfc_map_iterator;
  266. template< class MapT, class KeyT, class MappedT >
  267. struct mfc_map_iterator_super
  268. {
  269. typedef iterator_facade<
  270. mfc_map_iterator<MapT, KeyT, MappedT>,
  271. std::pair<KeyT, MappedT>,
  272. forward_traversal_tag,
  273. std::pair<KeyT, MappedT> const
  274. > type;
  275. };
  276. template< class MapT, class KeyT, class MappedT >
  277. struct mfc_map_iterator :
  278. mfc_map_iterator_super<MapT, KeyT, MappedT>::type
  279. {
  280. private:
  281. typedef mfc_map_iterator self_t;
  282. typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
  283. typedef typename super_t::reference ref_t;
  284. public:
  285. explicit mfc_map_iterator()
  286. { }
  287. explicit mfc_map_iterator(MapT const& map, POSITION pos) :
  288. m_pmap(boost::addressof(map)), m_posNext(pos)
  289. {
  290. increment();
  291. }
  292. explicit mfc_map_iterator(MapT const& map) :
  293. m_pmap(&map), m_pos(0) // end iterator
  294. { }
  295. template< class, class, class > friend struct mfc_map_iterator;
  296. template< class MapT_, class KeyT_, class MappedT_>
  297. mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
  298. m_pmap(other.m_pmap),
  299. m_pos(other.m_pos), m_posNext(other.m_posNext),
  300. m_key(other.m_key), m_mapped(other.m_mapped)
  301. { }
  302. private:
  303. MapT const *m_pmap;
  304. POSITION m_pos, m_posNext;
  305. KeyT m_key; MappedT m_mapped;
  306. friend class iterator_core_access;
  307. ref_t dereference() const
  308. {
  309. BOOST_ASSERT(m_pos != 0 && "out of range");
  310. return std::make_pair(m_key, m_mapped);
  311. }
  312. void increment()
  313. {
  314. BOOST_ASSERT(m_pos != 0 && "out of range");
  315. if (m_posNext == 0) {
  316. m_pos = 0;
  317. return;
  318. }
  319. m_pos = m_posNext;
  320. m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
  321. }
  322. bool equal(self_t const& other) const
  323. {
  324. BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
  325. return m_pos == other.m_pos;
  326. }
  327. };
  328. struct mfc_map_functions
  329. {
  330. template< class Iterator, class X >
  331. Iterator begin(X& x)
  332. {
  333. return Iterator(x, x.GetStartPosition());
  334. }
  335. template< class Iterator, class X >
  336. Iterator end(X& x)
  337. {
  338. return Iterator(x);
  339. }
  340. };
  341. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  342. // mfc_cpair_map_iterator
  343. //
  344. // used by ::CMap and ::CMapStringToString
  345. //
  346. template< class MapT, class PairT >
  347. struct mfc_cpair_map_iterator;
  348. template< class MapT, class PairT >
  349. struct mfc_pget_map_iterator_super
  350. {
  351. typedef iterator_facade<
  352. mfc_cpair_map_iterator<MapT, PairT>,
  353. PairT,
  354. forward_traversal_tag
  355. > type;
  356. };
  357. template< class MapT, class PairT >
  358. struct mfc_cpair_map_iterator :
  359. mfc_pget_map_iterator_super<MapT, PairT>::type
  360. {
  361. private:
  362. typedef mfc_cpair_map_iterator self_t;
  363. typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
  364. typedef typename super_t::reference ref_t;
  365. public:
  366. explicit mfc_cpair_map_iterator()
  367. { }
  368. explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
  369. m_pmap(boost::addressof(map)), m_pp(pp)
  370. { }
  371. template< class, class > friend struct mfc_cpair_map_iterator;
  372. template< class MapT_, class PairT_>
  373. mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
  374. m_pmap(other.m_pmap), m_pp(other.m_pp)
  375. { }
  376. private:
  377. MapT *m_pmap;
  378. PairT *m_pp;
  379. friend class iterator_core_access;
  380. ref_t dereference() const
  381. {
  382. BOOST_ASSERT(m_pp != 0 && "out of range");
  383. return *m_pp;
  384. }
  385. void increment()
  386. {
  387. BOOST_ASSERT(m_pp != 0 && "out of range");
  388. m_pp = m_pmap->PGetNextAssoc(m_pp);
  389. }
  390. bool equal(self_t const& other) const
  391. {
  392. BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
  393. return m_pp == other.m_pp;
  394. }
  395. };
  396. struct mfc_cpair_map_functions
  397. {
  398. template< class Iterator, class X >
  399. Iterator begin(X& x)
  400. {
  401. // Workaround:
  402. // Assertion fails if empty.
  403. // MFC document is wrong.
  404. #if !defined(NDEBUG)
  405. if (x.GetCount() == 0)
  406. return Iterator(x, 0);
  407. #endif
  408. return Iterator(x, x.PGetFirstAssoc());
  409. }
  410. template< class Iterator, class X >
  411. Iterator end(X& x)
  412. {
  413. return Iterator(x, 0);
  414. }
  415. };
  416. #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
  417. // maps
  418. //
  419. template< >
  420. struct customization< ::CMapPtrToWord > :
  421. mfc_map_functions
  422. {
  423. template< class X >
  424. struct meta
  425. {
  426. typedef void *key_t;
  427. typedef WORD mapped_t;
  428. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  429. typedef mutable_iterator const_iterator;
  430. };
  431. };
  432. template< >
  433. struct customization< ::CMapPtrToPtr > :
  434. mfc_map_functions
  435. {
  436. template< class X >
  437. struct meta
  438. {
  439. typedef void *key_t;
  440. typedef void *mapped_t;
  441. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  442. typedef mutable_iterator const_iterator;
  443. };
  444. };
  445. template< >
  446. struct customization< ::CMapStringToOb > :
  447. mfc_map_functions
  448. {
  449. template< class X >
  450. struct meta
  451. {
  452. typedef ::CString key_t;
  453. typedef ::CObject *mapped_t;
  454. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  455. typedef mutable_iterator const_iterator;
  456. };
  457. };
  458. template< >
  459. struct customization< ::CMapStringToPtr > :
  460. mfc_map_functions
  461. {
  462. template< class X >
  463. struct meta
  464. {
  465. typedef ::CString key_t;
  466. typedef void *mapped_t;
  467. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  468. typedef mutable_iterator const_iterator;
  469. };
  470. };
  471. template< >
  472. struct customization< ::CMapStringToString > :
  473. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  474. mfc_cpair_map_functions
  475. #else
  476. mfc_map_functions
  477. #endif
  478. {
  479. template< class X >
  480. struct meta
  481. {
  482. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  483. typedef typename X::CPair pair_t;
  484. typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
  485. typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
  486. #else
  487. typedef ::CString key_t;
  488. typedef ::CString mapped_t;
  489. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  490. typedef mutable_iterator const_iterator;
  491. #endif
  492. };
  493. };
  494. template< >
  495. struct customization< ::CMapWordToOb > :
  496. mfc_map_functions
  497. {
  498. template< class X >
  499. struct meta
  500. {
  501. typedef WORD key_t;
  502. typedef ::CObject *mapped_t;
  503. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  504. typedef mutable_iterator const_iterator;
  505. };
  506. };
  507. template< >
  508. struct customization< ::CMapWordToPtr > :
  509. mfc_map_functions
  510. {
  511. template< class X >
  512. struct meta
  513. {
  514. typedef WORD key_t;
  515. typedef void *mapped_t;
  516. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  517. typedef mutable_iterator const_iterator;
  518. };
  519. };
  520. // templates
  521. //
  522. template< class Type, class ArgType >
  523. struct customization< ::CArray<Type, ArgType> > :
  524. array_functions
  525. {
  526. template< class X >
  527. struct meta
  528. {
  529. typedef Type val_t;
  530. typedef val_t *mutable_iterator;
  531. typedef val_t const *const_iterator;
  532. };
  533. };
  534. template< class Type, class ArgType >
  535. struct customization< ::CList<Type, ArgType> > :
  536. list_functions
  537. {
  538. template< class X >
  539. struct meta
  540. {
  541. typedef Type val_t;
  542. typedef list_iterator<X, val_t> mutable_iterator;
  543. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  544. typedef list_iterator<X const, val_t const> const_iterator;
  545. #else
  546. typedef list_iterator<X const, val_t const, val_t const> const_iterator;
  547. #endif
  548. };
  549. };
  550. template< class Key, class ArgKey, class Mapped, class ArgMapped >
  551. struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
  552. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  553. mfc_cpair_map_functions
  554. #else
  555. mfc_map_functions
  556. #endif
  557. {
  558. template< class X >
  559. struct meta
  560. {
  561. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  562. typedef typename X::CPair pair_t;
  563. typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
  564. typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
  565. #else
  566. typedef Key key_t;
  567. typedef Mapped mapped_t;
  568. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  569. typedef mutable_iterator const_iterator;
  570. #endif
  571. };
  572. };
  573. template< class BaseClass, class PtrType >
  574. struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
  575. {
  576. template< class X >
  577. struct fun
  578. {
  579. typedef typename remove_pointer<PtrType>::type val_t;
  580. typedef typename mpl::if_< is_const<X>,
  581. val_t const,
  582. val_t
  583. >::type val_t_;
  584. typedef val_t_ * const result_type;
  585. template< class PtrType_ >
  586. result_type operator()(PtrType_ p) const
  587. {
  588. return static_cast<result_type>(p);
  589. }
  590. };
  591. template< class X >
  592. struct meta
  593. {
  594. typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
  595. typedef typename range_const_iterator<BaseClass>::type citer_t;
  596. typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
  597. typedef transform_iterator<fun<X const>, citer_t> const_iterator;
  598. };
  599. template< class Iterator, class X >
  600. Iterator begin(X& x)
  601. {
  602. return Iterator(boost::begin<BaseClass>(x), fun<X>());
  603. }
  604. template< class Iterator, class X >
  605. Iterator end(X& x)
  606. {
  607. return Iterator(boost::end<BaseClass>(x), fun<X>());
  608. }
  609. };
  610. template< class BaseClass, class PtrType >
  611. struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
  612. list_functions
  613. {
  614. template< class X >
  615. struct meta
  616. {
  617. typedef typename remove_pointer<PtrType>::type val_t;
  618. // not l-value
  619. typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
  620. typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
  621. };
  622. };
  623. template< class BaseClass, class KeyPtrType, class MappedPtrType >
  624. struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
  625. mfc_map_functions
  626. {
  627. template< class X >
  628. struct meta
  629. {
  630. typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
  631. typedef mutable_iterator const_iterator;
  632. };
  633. };
  634. // strings
  635. //
  636. #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  637. template< >
  638. struct customization< ::CString >
  639. {
  640. template< class X >
  641. struct meta
  642. {
  643. // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
  644. typedef TCHAR *mutable_iterator;
  645. typedef TCHAR const *const_iterator;
  646. };
  647. template< class Iterator, class X >
  648. typename mutable_<Iterator, X>::type begin(X& x)
  649. {
  650. return x.GetBuffer(0);
  651. }
  652. template< class Iterator, class X >
  653. Iterator begin(X const& x)
  654. {
  655. return x;
  656. }
  657. template< class Iterator, class X >
  658. Iterator end(X& x)
  659. {
  660. return begin<Iterator>(x) + x.GetLength();
  661. }
  662. };
  663. #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  664. } } // namespace boost::range_detail_microsoft
  665. // range customizations
  666. //
  667. // arrays
  668. //
  669. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  670. boost::range_detail_microsoft::using_type_as_tag,
  671. BOOST_PP_NIL, CByteArray
  672. )
  673. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  674. boost::range_detail_microsoft::using_type_as_tag,
  675. BOOST_PP_NIL, CDWordArray
  676. )
  677. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  678. boost::range_detail_microsoft::using_type_as_tag,
  679. BOOST_PP_NIL, CStringArray
  680. )
  681. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  682. boost::range_detail_microsoft::using_type_as_tag,
  683. BOOST_PP_NIL, CUIntArray
  684. )
  685. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  686. boost::range_detail_microsoft::using_type_as_tag,
  687. BOOST_PP_NIL, CWordArray
  688. )
  689. // lists
  690. //
  691. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  692. boost::range_detail_microsoft::using_type_as_tag,
  693. BOOST_PP_NIL, CObList
  694. )
  695. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  696. boost::range_detail_microsoft::using_type_as_tag,
  697. BOOST_PP_NIL, CPtrList
  698. )
  699. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  700. boost::range_detail_microsoft::using_type_as_tag,
  701. BOOST_PP_NIL, CStringList
  702. )
  703. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  704. boost::range_detail_microsoft::using_type_as_tag,
  705. BOOST_PP_NIL, CObArray
  706. )
  707. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  708. boost::range_detail_microsoft::using_type_as_tag,
  709. BOOST_PP_NIL, CPtrArray
  710. )
  711. // maps
  712. //
  713. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  714. boost::range_detail_microsoft::using_type_as_tag,
  715. BOOST_PP_NIL, CMapPtrToWord
  716. )
  717. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  718. boost::range_detail_microsoft::using_type_as_tag,
  719. BOOST_PP_NIL, CMapPtrToPtr
  720. )
  721. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  722. boost::range_detail_microsoft::using_type_as_tag,
  723. BOOST_PP_NIL, CMapStringToOb
  724. )
  725. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  726. boost::range_detail_microsoft::using_type_as_tag,
  727. BOOST_PP_NIL, CMapStringToPtr
  728. )
  729. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  730. boost::range_detail_microsoft::using_type_as_tag,
  731. BOOST_PP_NIL, CMapStringToString
  732. )
  733. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  734. boost::range_detail_microsoft::using_type_as_tag,
  735. BOOST_PP_NIL, CMapWordToOb
  736. )
  737. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  738. boost::range_detail_microsoft::using_type_as_tag,
  739. BOOST_PP_NIL, CMapWordToPtr
  740. )
  741. // templates
  742. //
  743. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  744. boost::range_detail_microsoft::using_type_as_tag,
  745. BOOST_PP_NIL, CArray, 2
  746. )
  747. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  748. boost::range_detail_microsoft::using_type_as_tag,
  749. BOOST_PP_NIL, CList, 2
  750. )
  751. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  752. boost::range_detail_microsoft::using_type_as_tag,
  753. BOOST_PP_NIL, CMap, 4
  754. )
  755. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  756. boost::range_detail_microsoft::using_type_as_tag,
  757. BOOST_PP_NIL, CTypedPtrArray, 2
  758. )
  759. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  760. boost::range_detail_microsoft::using_type_as_tag,
  761. BOOST_PP_NIL, CTypedPtrList, 2
  762. )
  763. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  764. boost::range_detail_microsoft::using_type_as_tag,
  765. BOOST_PP_NIL, CTypedPtrMap, 3
  766. )
  767. // strings
  768. //
  769. #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  770. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  771. boost::range_detail_microsoft::using_type_as_tag,
  772. BOOST_PP_NIL, CString
  773. )
  774. #endif
  775. #endif