mfc.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  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. // const CObList and const CPtrList both return a value (and probably always will)
  225. typedef list_iterator<X const, ::CObject const * const, ::CObject const * const> const_iterator;
  226. };
  227. };
  228. template< >
  229. struct customization< ::CPtrList > :
  230. list_functions
  231. {
  232. template< class X >
  233. struct meta
  234. {
  235. typedef list_iterator<X, void *> mutable_iterator;
  236. // const CObList and const CPtrList both return a value (and probably always will)
  237. typedef list_iterator<X const, void const * const, void const * const> const_iterator;
  238. };
  239. };
  240. template< >
  241. struct customization< ::CStringList > :
  242. list_functions
  243. {
  244. template< class X >
  245. struct meta
  246. {
  247. typedef ::CString val_t;
  248. typedef list_iterator<X, val_t> mutable_iterator;
  249. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  250. typedef list_iterator<X const, val_t const> const_iterator;
  251. #else
  252. typedef list_iterator<X const, val_t const, val_t const> const_iterator;
  253. #endif
  254. };
  255. };
  256. // mfc_map_iterator
  257. //
  258. template< class MapT, class KeyT, class MappedT >
  259. struct mfc_map_iterator;
  260. template< class MapT, class KeyT, class MappedT >
  261. struct mfc_map_iterator_super
  262. {
  263. typedef iterator_facade<
  264. mfc_map_iterator<MapT, KeyT, MappedT>,
  265. std::pair<KeyT, MappedT>,
  266. forward_traversal_tag,
  267. std::pair<KeyT, MappedT> const
  268. > type;
  269. };
  270. template< class MapT, class KeyT, class MappedT >
  271. struct mfc_map_iterator :
  272. mfc_map_iterator_super<MapT, KeyT, MappedT>::type
  273. {
  274. private:
  275. typedef mfc_map_iterator self_t;
  276. typedef typename mfc_map_iterator_super<MapT, KeyT, MappedT>::type super_t;
  277. typedef typename super_t::reference ref_t;
  278. public:
  279. explicit mfc_map_iterator()
  280. { }
  281. explicit mfc_map_iterator(MapT const& map, POSITION pos) :
  282. m_pmap(boost::addressof(map)), m_posNext(pos)
  283. {
  284. increment();
  285. }
  286. explicit mfc_map_iterator(MapT const& map) :
  287. m_pmap(&map), m_pos(0) // end iterator
  288. { }
  289. template< class, class, class > friend struct mfc_map_iterator;
  290. template< class MapT_, class KeyT_, class MappedT_>
  291. mfc_map_iterator(mfc_map_iterator<MapT_, KeyT_, MappedT_> const& other) :
  292. m_pmap(other.m_pmap),
  293. m_pos(other.m_pos), m_posNext(other.m_posNext),
  294. m_key(other.m_key), m_mapped(other.m_mapped)
  295. { }
  296. private:
  297. MapT const *m_pmap;
  298. POSITION m_pos, m_posNext;
  299. KeyT m_key; MappedT m_mapped;
  300. friend class iterator_core_access;
  301. ref_t dereference() const
  302. {
  303. BOOST_ASSERT(m_pos != 0 && "out of range");
  304. return std::make_pair(m_key, m_mapped);
  305. }
  306. void increment()
  307. {
  308. BOOST_ASSERT(m_pos != 0 && "out of range");
  309. if (m_posNext == 0) {
  310. m_pos = 0;
  311. return;
  312. }
  313. m_pos = m_posNext;
  314. m_pmap->GetNextAssoc(m_posNext, m_key, m_mapped);
  315. }
  316. bool equal(self_t const& other) const
  317. {
  318. BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
  319. return m_pos == other.m_pos;
  320. }
  321. };
  322. struct mfc_map_functions
  323. {
  324. template< class Iterator, class X >
  325. Iterator begin(X& x)
  326. {
  327. return Iterator(x, x.GetStartPosition());
  328. }
  329. template< class Iterator, class X >
  330. Iterator end(X& x)
  331. {
  332. return Iterator(x);
  333. }
  334. };
  335. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  336. // mfc_cpair_map_iterator
  337. //
  338. // used by ::CMap and ::CMapStringToString
  339. //
  340. template< class MapT, class PairT >
  341. struct mfc_cpair_map_iterator;
  342. template< class MapT, class PairT >
  343. struct mfc_pget_map_iterator_super
  344. {
  345. typedef iterator_facade<
  346. mfc_cpair_map_iterator<MapT, PairT>,
  347. PairT,
  348. forward_traversal_tag
  349. > type;
  350. };
  351. template< class MapT, class PairT >
  352. struct mfc_cpair_map_iterator :
  353. mfc_pget_map_iterator_super<MapT, PairT>::type
  354. {
  355. private:
  356. typedef mfc_cpair_map_iterator self_t;
  357. typedef typename mfc_pget_map_iterator_super<MapT, PairT>::type super_t;
  358. typedef typename super_t::reference ref_t;
  359. public:
  360. explicit mfc_cpair_map_iterator()
  361. { }
  362. explicit mfc_cpair_map_iterator(MapT& map, PairT *pp) :
  363. m_pmap(boost::addressof(map)), m_pp(pp)
  364. { }
  365. template< class, class > friend struct mfc_cpair_map_iterator;
  366. template< class MapT_, class PairT_>
  367. mfc_cpair_map_iterator(mfc_cpair_map_iterator<MapT_, PairT_> const& other) :
  368. m_pmap(other.m_pmap), m_pp(other.m_pp)
  369. { }
  370. private:
  371. MapT *m_pmap;
  372. PairT *m_pp;
  373. friend class iterator_core_access;
  374. ref_t dereference() const
  375. {
  376. BOOST_ASSERT(m_pp != 0 && "out of range");
  377. return *m_pp;
  378. }
  379. void increment()
  380. {
  381. BOOST_ASSERT(m_pp != 0 && "out of range");
  382. m_pp = m_pmap->PGetNextAssoc(m_pp);
  383. }
  384. bool equal(self_t const& other) const
  385. {
  386. BOOST_ASSERT(m_pmap == other.m_pmap && "iterators incompatible");
  387. return m_pp == other.m_pp;
  388. }
  389. };
  390. struct mfc_cpair_map_functions
  391. {
  392. template< class Iterator, class X >
  393. Iterator begin(X& x)
  394. {
  395. // Workaround:
  396. // Assertion fails if empty.
  397. // MFC document is wrong.
  398. #if !defined(NDEBUG)
  399. if (x.GetCount() == 0)
  400. return Iterator(x, 0);
  401. #endif
  402. return Iterator(x, x.PGetFirstAssoc());
  403. }
  404. template< class Iterator, class X >
  405. Iterator end(X& x)
  406. {
  407. return Iterator(x, 0);
  408. }
  409. };
  410. #endif // !defined(BOOST_RANGE_MFC_NO_CPAIR)
  411. // maps
  412. //
  413. template< >
  414. struct customization< ::CMapPtrToWord > :
  415. mfc_map_functions
  416. {
  417. template< class X >
  418. struct meta
  419. {
  420. typedef void *key_t;
  421. typedef WORD mapped_t;
  422. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  423. typedef mutable_iterator const_iterator;
  424. };
  425. };
  426. template< >
  427. struct customization< ::CMapPtrToPtr > :
  428. mfc_map_functions
  429. {
  430. template< class X >
  431. struct meta
  432. {
  433. typedef void *key_t;
  434. typedef void *mapped_t;
  435. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  436. typedef mutable_iterator const_iterator;
  437. };
  438. };
  439. template< >
  440. struct customization< ::CMapStringToOb > :
  441. mfc_map_functions
  442. {
  443. template< class X >
  444. struct meta
  445. {
  446. typedef ::CString key_t;
  447. typedef ::CObject *mapped_t;
  448. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  449. typedef mutable_iterator const_iterator;
  450. };
  451. };
  452. template< >
  453. struct customization< ::CMapStringToPtr > :
  454. mfc_map_functions
  455. {
  456. template< class X >
  457. struct meta
  458. {
  459. typedef ::CString key_t;
  460. typedef void *mapped_t;
  461. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  462. typedef mutable_iterator const_iterator;
  463. };
  464. };
  465. template< >
  466. struct customization< ::CMapStringToString > :
  467. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  468. mfc_cpair_map_functions
  469. #else
  470. mfc_map_functions
  471. #endif
  472. {
  473. template< class X >
  474. struct meta
  475. {
  476. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  477. typedef typename X::CPair pair_t;
  478. typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
  479. typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
  480. #else
  481. typedef ::CString key_t;
  482. typedef ::CString mapped_t;
  483. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  484. typedef mutable_iterator const_iterator;
  485. #endif
  486. };
  487. };
  488. template< >
  489. struct customization< ::CMapWordToOb > :
  490. mfc_map_functions
  491. {
  492. template< class X >
  493. struct meta
  494. {
  495. typedef WORD key_t;
  496. typedef ::CObject *mapped_t;
  497. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  498. typedef mutable_iterator const_iterator;
  499. };
  500. };
  501. template< >
  502. struct customization< ::CMapWordToPtr > :
  503. mfc_map_functions
  504. {
  505. template< class X >
  506. struct meta
  507. {
  508. typedef WORD key_t;
  509. typedef void *mapped_t;
  510. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  511. typedef mutable_iterator const_iterator;
  512. };
  513. };
  514. // templates
  515. //
  516. template< class Type, class ArgType >
  517. struct customization< ::CArray<Type, ArgType> > :
  518. array_functions
  519. {
  520. template< class X >
  521. struct meta
  522. {
  523. typedef Type val_t;
  524. typedef val_t *mutable_iterator;
  525. typedef val_t const *const_iterator;
  526. };
  527. };
  528. template< class Type, class ArgType >
  529. struct customization< ::CList<Type, ArgType> > :
  530. list_functions
  531. {
  532. template< class X >
  533. struct meta
  534. {
  535. typedef Type val_t;
  536. typedef list_iterator<X, val_t> mutable_iterator;
  537. #if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
  538. typedef list_iterator<X const, val_t const> const_iterator;
  539. #else
  540. typedef list_iterator<X const, val_t const, val_t const> const_iterator;
  541. #endif
  542. };
  543. };
  544. template< class Key, class ArgKey, class Mapped, class ArgMapped >
  545. struct customization< ::CMap<Key, ArgKey, Mapped, ArgMapped> > :
  546. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  547. mfc_cpair_map_functions
  548. #else
  549. mfc_map_functions
  550. #endif
  551. {
  552. template< class X >
  553. struct meta
  554. {
  555. #if !defined(BOOST_RANGE_MFC_NO_CPAIR)
  556. typedef typename X::CPair pair_t;
  557. typedef mfc_cpair_map_iterator<X, pair_t> mutable_iterator;
  558. typedef mfc_cpair_map_iterator<X const, pair_t const> const_iterator;
  559. #else
  560. typedef Key key_t;
  561. typedef Mapped mapped_t;
  562. typedef mfc_map_iterator<X, key_t, mapped_t> mutable_iterator;
  563. typedef mutable_iterator const_iterator;
  564. #endif
  565. };
  566. };
  567. template< class BaseClass, class PtrType >
  568. struct customization< ::CTypedPtrArray<BaseClass, PtrType> >
  569. {
  570. template< class X >
  571. struct fun
  572. {
  573. typedef typename remove_pointer<PtrType>::type val_t;
  574. typedef typename mpl::if_< is_const<X>,
  575. val_t const,
  576. val_t
  577. >::type val_t_;
  578. typedef val_t_ * const result_type;
  579. template< class PtrType_ >
  580. result_type operator()(PtrType_ p) const
  581. {
  582. return static_cast<result_type>(p);
  583. }
  584. };
  585. template< class X >
  586. struct meta
  587. {
  588. typedef typename compatible_mutable_iterator<BaseClass>::type miter_t;
  589. typedef typename range_const_iterator<BaseClass>::type citer_t;
  590. typedef transform_iterator<fun<X>, miter_t> mutable_iterator;
  591. typedef transform_iterator<fun<X const>, citer_t> const_iterator;
  592. };
  593. template< class Iterator, class X >
  594. Iterator begin(X& x)
  595. {
  596. return Iterator(boost::begin<BaseClass>(x), fun<X>());
  597. }
  598. template< class Iterator, class X >
  599. Iterator end(X& x)
  600. {
  601. return Iterator(boost::end<BaseClass>(x), fun<X>());
  602. }
  603. };
  604. template< class BaseClass, class PtrType >
  605. struct customization< ::CTypedPtrList<BaseClass, PtrType> > :
  606. list_functions
  607. {
  608. template< class X >
  609. struct meta
  610. {
  611. typedef typename remove_pointer<PtrType>::type val_t;
  612. // not l-value
  613. typedef list_iterator<X, val_t * const, val_t * const> mutable_iterator;
  614. typedef list_iterator<X const, val_t const * const, val_t const * const> const_iterator;
  615. };
  616. };
  617. template< class BaseClass, class KeyPtrType, class MappedPtrType >
  618. struct customization< ::CTypedPtrMap<BaseClass, KeyPtrType, MappedPtrType> > :
  619. mfc_map_functions
  620. {
  621. template< class X >
  622. struct meta
  623. {
  624. typedef mfc_map_iterator<X, KeyPtrType, MappedPtrType> mutable_iterator;
  625. typedef mutable_iterator const_iterator;
  626. };
  627. };
  628. // strings
  629. //
  630. #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  631. template< >
  632. struct customization< ::CString >
  633. {
  634. template< class X >
  635. struct meta
  636. {
  637. // LPTSTR/LPCTSTR is not always defined in <tchar.h>.
  638. typedef TCHAR *mutable_iterator;
  639. typedef TCHAR const *const_iterator;
  640. };
  641. template< class Iterator, class X >
  642. typename mutable_<Iterator, X>::type begin(X& x)
  643. {
  644. return x.GetBuffer(0);
  645. }
  646. template< class Iterator, class X >
  647. Iterator begin(X const& x)
  648. {
  649. return x;
  650. }
  651. template< class Iterator, class X >
  652. Iterator end(X& x)
  653. {
  654. return begin<Iterator>(x) + x.GetLength();
  655. }
  656. };
  657. #endif // defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  658. } } // namespace boost::range_detail_microsoft
  659. // range customizations
  660. //
  661. // arrays
  662. //
  663. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  664. boost::range_detail_microsoft::using_type_as_tag,
  665. BOOST_PP_NIL, CByteArray
  666. )
  667. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  668. boost::range_detail_microsoft::using_type_as_tag,
  669. BOOST_PP_NIL, CDWordArray
  670. )
  671. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  672. boost::range_detail_microsoft::using_type_as_tag,
  673. BOOST_PP_NIL, CStringArray
  674. )
  675. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  676. boost::range_detail_microsoft::using_type_as_tag,
  677. BOOST_PP_NIL, CUIntArray
  678. )
  679. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  680. boost::range_detail_microsoft::using_type_as_tag,
  681. BOOST_PP_NIL, CWordArray
  682. )
  683. // lists
  684. //
  685. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  686. boost::range_detail_microsoft::using_type_as_tag,
  687. BOOST_PP_NIL, CObList
  688. )
  689. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  690. boost::range_detail_microsoft::using_type_as_tag,
  691. BOOST_PP_NIL, CPtrList
  692. )
  693. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  694. boost::range_detail_microsoft::using_type_as_tag,
  695. BOOST_PP_NIL, CStringList
  696. )
  697. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  698. boost::range_detail_microsoft::using_type_as_tag,
  699. BOOST_PP_NIL, CObArray
  700. )
  701. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  702. boost::range_detail_microsoft::using_type_as_tag,
  703. BOOST_PP_NIL, CPtrArray
  704. )
  705. // maps
  706. //
  707. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  708. boost::range_detail_microsoft::using_type_as_tag,
  709. BOOST_PP_NIL, CMapPtrToWord
  710. )
  711. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  712. boost::range_detail_microsoft::using_type_as_tag,
  713. BOOST_PP_NIL, CMapPtrToPtr
  714. )
  715. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  716. boost::range_detail_microsoft::using_type_as_tag,
  717. BOOST_PP_NIL, CMapStringToOb
  718. )
  719. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  720. boost::range_detail_microsoft::using_type_as_tag,
  721. BOOST_PP_NIL, CMapStringToPtr
  722. )
  723. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  724. boost::range_detail_microsoft::using_type_as_tag,
  725. BOOST_PP_NIL, CMapStringToString
  726. )
  727. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  728. boost::range_detail_microsoft::using_type_as_tag,
  729. BOOST_PP_NIL, CMapWordToOb
  730. )
  731. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  732. boost::range_detail_microsoft::using_type_as_tag,
  733. BOOST_PP_NIL, CMapWordToPtr
  734. )
  735. // templates
  736. //
  737. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  738. boost::range_detail_microsoft::using_type_as_tag,
  739. BOOST_PP_NIL, CArray, 2
  740. )
  741. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  742. boost::range_detail_microsoft::using_type_as_tag,
  743. BOOST_PP_NIL, CList, 2
  744. )
  745. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  746. boost::range_detail_microsoft::using_type_as_tag,
  747. BOOST_PP_NIL, CMap, 4
  748. )
  749. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  750. boost::range_detail_microsoft::using_type_as_tag,
  751. BOOST_PP_NIL, CTypedPtrArray, 2
  752. )
  753. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  754. boost::range_detail_microsoft::using_type_as_tag,
  755. BOOST_PP_NIL, CTypedPtrList, 2
  756. )
  757. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(
  758. boost::range_detail_microsoft::using_type_as_tag,
  759. BOOST_PP_NIL, CTypedPtrMap, 3
  760. )
  761. // strings
  762. //
  763. #if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
  764. BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(
  765. boost::range_detail_microsoft::using_type_as_tag,
  766. BOOST_PP_NIL, CString
  767. )
  768. #endif
  769. #endif